oracle 如何把单行记录拆分为多行
【问题】
表:
xh kc
1 语文,数学,英语
2 政治,历史,地理
3 地理,语文
4 地理,数学
想把上面的表拆分为:
1 语文
1 数学
1 英语
2 政治
2 历史
2 地理
4 地理
4 数学
3 地理
3 语文
按照学号,把课程拆分
【回答】
Oracle 中可以使用层次查询语句结合子查询或随机数完成,这里给出两种写法:
写法 1:
SELECT xh,REGEXP_SUBSTR(kc,'\[^,\]+',1,rn) kc
FROM t0052,
(SELECT LEVEL rn
FROM DUAL
CONNECT BY LEVEL<=(SELECT
MAX(length(trim(translate(kc,replace(kc,','),' '))))+1
FROM t0052))
WHERE REGEXP_SUBSTR(kc,'\[^,\]+',1,rn) IS NOT NULL
写法 2:
select xh,regexp_substr(kc,'\[^,\]+',1,level) kc
from t0052
connect by level <= (length(kc)-length(regexp_replace(kc,'\[^,\]+','')))
and rowid= prior rowid
and prior dbms_random.value is not null;
可以看到上面的两种写法比较复杂,且其中使用了 Oracle 的一些技巧(如为了避免循环错误使用的 prior dbms_random.value is not null),对于使用者有一定难度,而且更换数据库就不能执行了。
这种情况建议使用 SPL 来做,脚本如下:
A |
|
1 |
$SELECT XH,KC FROM t0052 |
2 |
=A1.news(KC.array();XH,~:KC) |
可以看到集算脚本非常简单,其中 A2 即所得结果集:
集算器提供 JDBC 接口,可以像数据库一样嵌入到应用程序中,用起来很简单,详细可参考【Java 如何调用 SPL 脚本】。