繁体   English   中英

是否有一个Oracle函数来确定重复字符的数量

[英]Is there an Oracle Function to determine the number of repeat character

我需要验证电子邮件中重复字符的数量。

我尝试下一个给出重复字符百分比的代码,但仅当字符彼此相邻时才起作用。 因此,有可能按字符顺序订购电子邮件以获得我的结果。

SELECT 
round(((REGEXP_COUNT(regexp_replace(SUBSTR('999824123@HOTMAIL.COM',1,INSTR('989824123@HOTMAIL.COM', '@', 1)-1), '(.)\1+','&'),'&')+length(SUBSTR('989824123@HOTMAIL.COM',1,INSTR('989824123@HOTMAIL.COM', '@', 1)-1)) - length(regexp_replace(SUBSTR('989824123@HOTMAIL.COM',1,INSTR('989824123@HOTMAIL.COM', '@', 1)-1), '(.)\1+','\1')))* 100)/length(SUBSTR('989824123@HOTMAIL.COM',1,INSTR('989824123@HOTMAIL.COM', '@', 1)-1)),2) AS PORCENTAJE_IGUAL  
FROM DUAL A;

我希望此电子邮件989824123@HOTMAIL.COM的重复字符有60%。 不包含域。

请帮忙。

PD:对不起,英语不好

数字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;

您也可以在没有功能的情况下直接使用上述解决方案进行选择,以下是示例:

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查询进行connect by往往比较慢。 也许您可以调整您的regexp函数,它将更快。 我尝试这样做,但是您的regexp_replace99更改为$ ,将999更改为1 $

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM