SQL:如何将组合行分成单独的行

时间:2012-05-10 14:26:19

标签: sql sql-server oracle stored-procedures tokenize

我有一个这样的数据库表:

id   |   check_number        |   amount
1    |   1001]1002]1003      |   200]300]100
2    |   2001]2002           |   500]1000
3    |   3002]3004]3005]3007 |   100]300]600]200

我想将记录分成以下内容:

id   |   check_number    |   amount
1    |   1001            |   200
2    |   1002            |   300
3    |   1003            |   100
.    |     .             |    .
.    |     .             |    .
.    |     .             |    .

如何在Oracle和SQL Server中使用SQL?

谢谢,

米洛

1 个答案:

答案 0 :(得分:2)

在Oracle Only中,使用CONNECT BY LEVEL方法(参见here),但有几点需要注意:

select rownum, id,
       substr(']'||check_number||']'
              ,instr(']'||check_number||']',']',1,level)+1
              ,instr(']'||check_number||']',']',1,level+1) 
               - instr(']'||check_number||']',']',1,level) - 1) C1VALUE,
       substr(']'||amount||']'
              ,instr(']'||amount||']',']',1,level)+1
              ,instr(']'||amount||']',']',1,level+1) 
               - instr(']'||amount||']',']',1,level) - 1) C2VALUE
    from table
connect by id = prior id and prior dbms_random.value is not null  
      and level <= length(check_number) - length(replace(check_number,']')) + 1


ROWNUM ID  C1VALUE C2VALUE

1      1   1001    200
2      1   1002    300
3      1   1003    100
4      2   2001    500
5      2   2002    1000
6      3   3002    100
7      3   3004    300
8      3   3005    600
9      3   3007    200

基本上我们使用oracle的分层函数来断开查询,然后只获取check_number和amount列中数据的每个“列”中数据的子字符串。

主要警告:要转换的数据必须在两列中具有相同数量的“数据元素”,因为我们使用第一列来“计算”要转换的项目数。

我在11gR2上测试了这个。 YMMV也取决于DMBS版本。注意需要使用“PRIOR”运算符,它可以防止oracle通过循环进入无限连接。