这个需求看上去比较简单,但是要完成却不是那么轻松的可以做到。

首先看一个例子,假如有若干个手机号码:

13677884444

13988400965

13973250074

13974416087

13999750304

13967311183

13999806632

要找出其中有连续3-8个数字是相同的号码,该如何找?

期初我以为可以用正则很方便的实现,结果想了半天也想不出简洁的匹配模式。只好另辟蹊径了。我想了下,关键问题是如何构建连续3-8个0-9的数字,只要有了这些数字,接下来我们只要找出手机号码中含有这些数字串的就行了。下文给出了几种构造的方式:

1、数字拼接法。即首先生成若干数字,然后按照一定序号通过字符串拼接函数拼接大于该序号的字符串即可。

2、rpad+笛卡尔积法。先构造0-9共10个数字,长度为8的数字串,然后通过笛卡尔及扩展到60个,再按照组内序号进行字符串截断。

3、直接rpad法。构造0-9共10个数字,每个数字重复6次,共60行数字串。然后以数字为分组取组内序号,用rpad进行构建。

4、半正则法。即对0-9每个数字做{3,8}匹配。

下面是几个算法的具体介绍:

数字拼接法:

with

tmp as(select '139' || trunc(dbms_random.value(100000000, 1000000000)) aa

from dual connect by rownum <= 10000),

ttt as (select replace(ssum(c1), ',') c1, replace(ssum(c2), ',') c2,

replace(ssum(c3), ',') c3, replace(ssum(c4), ',') c4,

replace(ssum(c5), ',') c5, replace(ssum(c6), ',') c6

from (select a.rn,

decode(sign(row_number()over(partition by a.rn order by rownum)-4), -1, a.rn) c1,

decode(sign(row_number()over(partition by a.rn order by rownum)-5), -1, a.rn) c2,

decode(sign(row_number()over(partition by a.rn order by rownum)-6), -1, a.rn) c3,

decode(sign(row_number()over(partition by a.rn order by rownum)-7), -1, a.rn) c4,

decode(sign(row_number()over(partition by a.rn order by rownum)-8), -1, a.rn) c5,

decode(sign(row_number()over(partition by a.rn order by rownum)-9), -1, a.rn) c6

from (select rownum - 1 rn from dual connect by rownum <= 10) a,

(select rownum rn from dual connect by rownum <= 8) b)

group by rn)

select * from tmp t, ttt x

where instr(t.aa, x.c1) > 0

or instr(t.aa, x.c2) > 0

or instr(t.aa, x.c3) > 0

or instr(t.aa, x.c4) > 0

or instr(t.aa, x.c5) > 0

or instr(t.aa, x.c6) > 0

查询结果是对的,但是发现一个问题,就是速度太慢,查出100条,就花了26s。看来要把ttt这个表实体化,这样查询才能快点了。事实证明了我的观点,实体化后100条花了0.25s。

rpad+笛卡尔积法

但是我又有了一个想法,能不能不实体化,也让他速度这么快呢?要实现这个目的,只能修改数字串的构造方式了。我们的目的只有一个,构造3-8个0-9的数字串。按照这样的思路,我想到了lpad函数,先构造10行数字(0-9),然后用lpad进行补差:

SQL> select lpad(rownum-1, 8, rownum-1) from dual connect by rownum <= 10;

LPAD(ROWNUM-1,8,ROWNUM-1)

-------------------------

00000000

11111111

22222222

33333333

44444444

55555555

66666666

77777777

88888888

99999999

10 rows selected

这样便快速得到了我们要的数字串,然后就是每个数字串扩展(3-8):

SQL> select substr(a.n, 1, r) nn

2    from (select lpad(rownum-1, 8, rownum-1) n from dual connect by rownum <= 10) a,

3         (select rownum + 2 r from dual connect by rownum <= 6) b

4  /

NN

--------------------------------

000

0000

00000

000000

0000000

00000000

111

1111

11111

111111

1111111

11111111

222

2222

22222

222222

2222222

22222222

333

3333

33333

333333

3333333

33333333

444

4444

44444

444444

4444444

44444444

555

5555

55555

555555

5555555

55555555

666

6666

66666

666666

6666666

66666666

777

7777

77777

777777

7777777

77777777

888

8888

88888

888888

8888888

88888888

999

9999

99999

999999

9999999

99999999

60 rows selected

ok,大功告成,接下去就是匹配了:

SQL> with

2  tmp as(select '139' || trunc(dbms_random.value(100000000, 1000000000)) aa

3           from dual connect by rownum <= 10000),

4  ttt as (select substr(a.n, 1, r) l

5    from (select lpad(rownum-1, 8, rownum-1) n from dual connect by rownum <= 10) a,

6         (select rownum + 2 r from dual connect by rownum <= 6) b)

7  select p.aa from tmp p, ttt t

8   where instr(p.aa, t.l) >= 1

9  /

AA

-------------------------------------------

139628435559

139111449653

139927388845

139323055525

139947487666

139777541560

.....

100条在0.4s左右。

直接rpad法

上面用的是笛卡尔积构建法,能不能直接就构建60行数字串呢?语句如下:

with

tmp as(select '139' || trunc(dbms_random.value(100000000, 1000000000)) aa

from dual connect by rownum <= 10000),

ttt as (select rpad(lv, row_number()over(partition by lv order by lv)+2, lv) l

from (select ceil(level/6)-1 lv

from dual

connect by level <= 60))

select p.aa from tmp p, ttt t

where instr(p.aa, t.l) >= 1

方法是先构建0-9的数字,每个数字各6行,共60行数字。然后,row_number按数字分组,取组内序号(1-6),并+2(3-8),然后用rpad补差,时间上花费与前面笛卡尔积构建的差不多,都在0.4s左右。

半正则法

最后,再给出半正则的查询法:

with

tmp as(select '139' || trunc(dbms_random.value(100000000, 1000000000)) aa

from dual connect by rownum <= 10000),

ttt as (select rownum - 1 r from dual connect by rownum <= 10)

select p.aa from tmp p, ttt t

where regexp_like(p.aa, t.r||'{3,8}')

原理不多说了,很简单的,你懂的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12932950/viewspace-687908/,如需转载,请注明出处,否则将追究法律责任。

oracle查手机号码位数重复,连续相同号码的识别相关推荐

  1. oracle 查的数据去重复数据,Oracle查询和过滤重复数据

    对数据库某些意外情况,引起的重复数据,如何处理呢? ----------------查重复: select * from satisfaction_survey s where s.as_side = ...

  2. oracle索引自增函数,oracle生成动态前缀且自增号码的函数分享

    create or replace Function GetInvitationNO(prev varchar2, num1 varchar2, num2 varchar2, sessionSetti ...

  3. oracle删除重复字段数据库,用Oracle的分析函数删除重复的数据,

    用Oracle的分析函数删除重复的数据, 用Oracle的分析函数删除重复的数据 没有主键(Primary Key)约束保护的表格可能会让重复的数据行被插入进来.查找这种重复数据的传统方式是通过GRO ...

  4. 根据ICCID反查手机号码的五种终极方法

    摘要: 然后提供ICCID,要求警察陪同去当地ICCID对应的运营商营业厅,提供ICCID,查询对应号码!只有在警察同志的陪同或者警察开具的证明,运营商才会配合帮助查询对应号码.在中国丢手机这样的事情 ...

  5. mysql手机号码不重复吗_如何批量生成MySQL不重复手机号大表实例代码

    前言 在MySQL很多测试场景,需要人工生成一些测试数据来测试.本文提供一个构造MySQL大表存储过程,可以生成包含用户名,手机号码,出生日期等字段.也可以通过滤重来使得手机号码不重复,模拟现实场景. ...

  6. 用Oracle的分析函数删除重复的表格

    用Oracle的分析函数删除重复的表格 作者: Bob Watkins 没有主键(Primary Key)约束保护的表格可能会让重复的数据行被插入进来.查找这种重复数据的传统方式是通过GROUP BY ...

  7. oracle的sid相同如何解决,oracle数据库的SID重复有关问题

    oracle数据库的SID重复问题 1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务. 2. 开始->程序->Oracle - OraH ...

  8. 使用ChatGPT帮我们写一篇论文,最后查重的重复率会是多少?

    使用ChatGPT帮我们写一篇论文,最后查重的重复率会是多少? ChatGpt一经发布就大火,迅速应用在各个领域,尤其在程序圈自动帮我们写代码着实是圈了一大波粉.那么它用在科研领域会出现怎样的效果呢, ...

  9. oracle 提取手机号码

    oracle 提取手机号码 select dh, regexp_replace(dh, '.*(1[[:digit:]]{10}).*','\1') from table where regexp_l ...

最新文章

  1. 我们破解了几乎所有智能手机的人脸识别,唯独没有iPhone
  2. 一些很酷的.Net技
  3. docker安装nexus3命令
  4. 你绝对想不到R文件找不到(cannot resolve symbol R)的原因
  5. POJ - 3020 Antenna Placement(最小路径覆盖-二分图最大匹配)
  6. 作为开发者发布小程序_如何建立个人品牌作为新开发者
  7. 关于OpenCV中IplImage的字节对齐问题
  8. 【笔记】面向对象设计模式
  9. 还有 2 天,这场大咖云集的启智开发者大会即将启动!
  10. [Java] 蓝桥杯BASIC-24 基础练习 龟兔赛跑预测
  11. 用python输出杨辉三角形,python输出杨辉三角
  12. 万字雄文前瞻丨区块链及隐私计算在传统企业中的技术认知与进阶思考
  13. 2021 IDEA最新版安装教程(可激活)
  14. swper插件:刷新页面,banner轮播图出不来
  15. Python+Vue计算机毕业设计个人学习博客系统wyz5v(源码+程序+LW+部署)
  16. 解决WORD “未找到引用源”问题
  17. Linux-软件安装管理
  18. 我在木星——开始也意味着不再安逸
  19. 今日科普:MEMS传感器的应用案例介绍
  20. 394计算机毕业设计

热门文章

  1. 从实例重温工厂模式和单件模式
  2. 经验:从ppt复制到word中的图片在导出成PDF后出现黑框怎么解决
  3. python+autoit用法
  4. 用php数组做一个表格,一个非常好用的PHP数组函数
  5. 2022年广东工业大学文远知行杯新生程序设计竞赛(10/13)
  6. Thymeleaf 普通input赋值和textarea标签赋值区别
  7. 服务器是多用户服务的计算机,Windows2008服务器创建多个远程登录用户的方法,添加新用户...
  8. php 表单页面跳转,form表单页面跳转方式提交练习
  9. linux版本高斯安装,RedHat Linux系统Gaussian高斯的安装与出错信息
  10. react-native 热更新expo-update使用心得