我有以下一行A1,A2,A3; A4,A5,A6 我想将数据查询为2行:A1,A2,A3和A4,A5,A6
下面的查询返回A1,A2,A3的多行:
select regexp_substr(value, '[^;]+', 1, level)
from some_table
where some_id = 8
connect by regexp_substr(value, '[^;]+', 1, level) is not null
;
答案 0 :(得分:2)
您可以使用递归子查询分解子句和简单的字符串函数(而不是慢速的正则表达式)来做到这一点。
(注意:当层次结构查询有多个输入行时,在每个深度生成指数级增加的输出行,因为它无法将每一行与其父级相关联,因此它也将与之相关联,所以这也没有问题上一个层次结构级别的所有行。)
Oracle设置:
CREATE TABLE some_table( some_id, value ) AS
SELECT 8, 'A1,A2,A3;A4,A5,A6' FROM DUAL UNION ALL
SELECT 8, 'B1,B2,B3;B4,B5,B6' FROM DUAL UNION ALL
SELECT 8, 'C1,C2,C3;C4,C5,C6' FROM DUAL;
查询:
WITH line_start_end ( some_id, value, startidx, endidx ) AS (
SELECT some_id,
value,
1,
INSTR( value, ';', 1 )
FROM some_table
WHERE some_id = 8
UNION ALL
SELECT some_id,
value,
endidx + 1,
INSTR( value, ';', endidx + 1 )
FROM line_start_end
WHERE endidx > 0
)
SELECT some_id,
CASE
WHEN endidx = 0
THEN SUBSTR( value, startidx )
ELSE SUBSTR( value, startidx, endidx - startidx )
END AS value
FROM line_start_end;
输出:
SOME_ID | VALUE ------: | :------- 8 | A1,A2,A3 8 | B1,B2,B3 8 | C1,C2,C3 8 | A4,A5,A6 8 | B4,B5,B6 8 | C4,C5,C6
db <>提琴here
答案 1 :(得分:1)
根据MT0的示例数据(谢谢,MT0!),这是避免重复行的方法。
SQL> CREATE TABLE some_table( some_id, value ) AS
2 SELECT 8, 'A1,A2,A3;A4,A5,A6' FROM DUAL UNION ALL
3 SELECT 8, 'B1,B2,B3;B4,B5,B6' FROM DUAL UNION ALL
4 SELECT 8, 'C1,C2,C3;C4,C5,C6' FROM DUAL;
Table created.
SQL> select some_id, regexp_substr(value, '[^;]+', 1, column_value) result
2 from some_table cross join
3 table(cast(multiset(select level from dual
4 connect by level <= regexp_count(value, ';') + 1
5 ) as sys.odcinumberlist ));
SOME_ID RESULT
---------- -----------------
8 A1,A2,A3
8 A4,A5,A6
8 B1,B2,B3
8 B4,B5,B6
8 C1,C2,C3
8 C4,C5,C6
6 rows selected.
SQL>