当前位置: 代码迷 >> Oracle技术 >> 一路高级SQL题
  详细解决方案

一路高级SQL题

热度:81   发布时间:2016-04-24 08:08:32.0
一道高级SQL题
表结构和数据如下:
ID     NAME
1      E1~E4
2      F3~F9
。。。。。

要求实现如下效果:
1      E1
1      E2
1      E3
1      E4
2      F3
2      F4
2      F5
2      F6
2      F7
2      F8
2      F9

------解决方案--------------------
引用:
表结构和数据如下:
ID     NAME
1      E1~E4
2      F3~F9
。。。。。

要求实现如下效果:
1      E1
1      E2
1      E3
1      E4
2      F3
2      F4
2      F5
2      F6
2      F7
2      F8
2      F9


select id, nm 
------解决方案--------------------
 (level + fr_num - 1)
  from (SELECT t1.id id,
               regexp_substr(t1.name, '[[:alpha:]]', 1, 1) nm,
               regexp_substr(t1.name, '[[:digit:]]', 1, 1) fr_num,
               regexp_substr(t1.name, '[[:digit:]]', 1, 2) to_num
          FROM T1)
connect by level <= to_num - fr_num + 1
       and id = prior id
       and prior dbms_random.value is not null;

------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:


select id, nm 
------解决方案--------------------
 (level + fr_num - 1)
  from (SELECT t1.id id,
               regexp_substr(t1.name, '[[:alpha:]]', 1, 1) nm,
               regexp_substr(t1.name, '[[:digit:]]', 1, 1) fr_num,
               regexp_substr(t1.name, '[[:digit:]]', 1, 2) to_num
          FROM T1)
connect by level <= to_num - fr_num + 1
       and id = prior id
       and prior dbms_random.value is not null;

版主,你这个高级SQ我L没太看懂,求解释下,谢谢!

regexp_substr(t1.name, '[[:alpha:]]', 1, 1)  取字母
regexp_substr(t1.name, '[[:digit:]]', 1, 1)  取首个数字
regexp_substr(t1.name, '[[:digit:]]', 1, 2) 取第二个数字
level <= to_num - fr_num + 1 循环次数,如fr_num=1,to_num=4,那么循环4-1+1=4次
id = prior id 在每组ID中循环,如ID=1循环完了后,id=2内又从level=1开始循环
prior dbms_random.value is not null ORACLE有个检查,如果有前后连接条件(id=PRIOR id),但是同一行数据再次出现,它就会报一个错:ERROR:ORA-01436: CONNECT BY loop in user data 为了欺骗它,这里用了一个PRIOR DBMS_RANDOM.VALUE, 因为DBMS_RANDOM.VALUE每次调用都返回不同结果,所以它认为两行数据不一样,所以不报错了。

但是 这个正则截取只能截取一位数字。E2-E12。


select id, nm 
------解决方案--------------------
 (level + fr_num - 1)
  from (SELECT t1.id id,
               regexp_substr(t1.name, '[[:alpha:]]', 1, 1) nm,
               regexp_substr(t1.name, '[0-9]+', 1, 1) fr_num,
               regexp_substr(t1.name, '[0-9]+', 1, 2) to_num
          FROM T1)
connect by level <= to_num - fr_num + 1
       and id = prior id
       and prior dbms_random.value is not null;

------解决方案--------------------
  相关解决方案