2012-05-10 20 views
2

我有一个数据库表是这样的:SQL:如何合并行分成单独的行

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?

感谢,

米洛

+2

你想用'id'列做什么?为转换后的数据集生成一个新值? – Phil

+1

'sql-server'或'oracle'?或者你在两个RDBMS上真的有这个问题吗? – MatBailie

+1

什么是数据的来源?在将数据加载到数据库之前,您是否可以选择重新格式化数据? –

回答

2

在Oracle仅使用CONNECT BY水平的方法(见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 

本质上讲,我们吹熄使用分层查询函数,然后只获取check_number和amount列中每个“列”数据中的数据的子字符串。

主要的警告:数据被转化必须有相同数量的两列“数据元素”的,因为我们使用的首列“计数”进行改造的项目数。

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

+0

编辑 - 通过连接没有check_number。查询应该现在运行。 –

+1

在SQL Server中,可以使用递归CTE进行类似的操作。 –