Oracle一列转多行
1、新建测试表,录入测试数据。
CREATE TABLE TEST_ONE(
ID VARCHAR2(5),
NAME VARCHAR2(100)
);
INSERT INTO TEST_ONE (ID,NAME) VALUES('1','A:语文;B:数学;C:物理;D:化学;E:生物;');
INSERT INTO TEST_ONE (ID,NAME) VALUES('2','x:历史;y:地理;z:政治;');

2、进行数据分行处理。
SELECT ID,KEY,RN,
SUBSTR(STR, INSTR(STR, ';', 1, RN)+1,
INSTR(STR, ':', 1, RN) - INSTR(STR, ';', 1, RN) - 1) "First_Str",
SUBSTR(STR, INSTR(STR, ':', 1, RN)+1,
INSTR(STR, ';', 1, RN+1) - INSTR(STR, ':', 1, RN) - 1) "Second_Str"
FROM (SELECT ID,NAME KEY,';'||NAME STR FROM TEST_ONE) A,
(SELECT ROWNUM RN FROM DUAL CONNECT BY ROWNUM < 10) B
WHERE INSTR(STR, ';', 1, RN+1) > 0
ORDER BY A.ID,B.RN;

3、语句解释1:
原始数据处理,最前面添加对应数据分隔符(演示是“;”);便于下一步分隔数据。
注:"||" 为字符串连接符。
SELECT ID,NAME KEY,';'||NAME STR FROM TEST_ONE

4、语句解释2:
注:"CONNECT BY"是层次查询子句,一般用于树或者层次结果集的查询。
根据实际查询结果行数,适当修改"ROWNUM"的值。
SELECT ROWNUM RN FROM DUAL CONNECT BY ROWNUM < 10

5、语句解释3:
对字符串进行分割,首先查询出特殊符号位置,然后算出前后串之间字符长度进行截取。
SUBSTR(STR, INSTR(STR, ';', 1, RN)+1, INSTR(STR, ':', 1, RN) - INSTR(STR, ';', 1, RN) - 1) "First_Str"
6、语句解释4:
通过判断特殊符号最后位置,进行显示截取(防止层次查询中过多部分显示空值)。
WHERE INSTR(STR, ';', 1, RN+1) > 0