Числа 9, 8, 2 повторяются в электронной почте, поэтому у нас есть 6 символов (9, 9, 8, 8, 2, 2), которые повторяются, и 3 уникальных (1, 3, 4).6/9 дает нам 66,67%.Вы можете использовать этот запрос для подсчета:
with
t(email) as (select '989824123@hotmail.com' from dual),
a(email) as (select substr(email, 1,instr(email, '@', 1)-1) from t),
l as (select substr(email, level, 1) ltr from a connect by level <= length(email))
select sum(case when cnt <> 1 then cnt end) / sum(cnt)
from (select ltr, count(1) cnt from l group by ltr)
Я вырезал домен, затем в подзапросе l
Я разделил строку на однобуквенные строки, остальное было только для подсчета неуникальных символов и деления на числоиз всех символов.
изменить:
как применить что-то подобное в обновлении или выбрать для крупномасштабной базы данных с большим количеством электронной почты?
Вы можете создать функцию:
create or replace function rpt_similarity(i_email in varchar2) return number is
v_email varchar2(100);
v_ret number;
begin
v_email := substr(i_email, 1, instr(i_email, '@', 1) - 1);
with l as (
select substr(v_email, level, 1) ltr
from dual
connect by level <= length(v_email))
select sum(case when cnt <> 1 then cnt end) / sum(cnt)
into v_ret
from (select ltr, count(1) cnt from l group by ltr);
return v_ret;
end;
и использовать ее как здесь:
select rpt_similarity('abxabc@pqr.com') from dual;
или:
select rpt_similarity(email) from your_table;
Также выВы можете использовать вышеуказанное решение в select напрямую, без функции, вот пример:
create table test(id, email) as (
select 101, '989824123@hotmail.com' from dual union all
select 102, 'hsimpson@gmail.com' from dual union all
select 103, 'msimpson@gmail.com' from dual union all
select 104, 'bsimpson121314@hotmail.com' from dual union all
select 105, 'abxabx@hotmail.com' from dual );
with
a(id, email) as (select id, substr(email, 1,instr(email, '@', 1)-1) from test),
l as (
select id, email, substr(email, level, 1) ltr from a
connect by level <= length(email)
and prior id = id and prior sys_guid() is not null)
select id, email, sum(case when cnt <> 1 then cnt end) / sum(cnt)
from (select id, email, ltr, count(1) cnt from l group by id, ltr, email)
group by id, email;
connect by
запросы имеют тенденцию быть медленными для больших наборов данных.Возможно, вы сможете адаптировать свои функции regexp
, и это будет быстрее.Я пытался сделать это, но ваш regexp_replace
превращается 99
в $
и 999
также в один $
.