我正在尝试将一列中用逗号分隔的列表拆分为不同的行。例如:
with testdata(vala,valb,valc) as(
select
'1,2,3,4' as vala,
'5,6,7,8' as valb,
'9,10,11' as valc
from dual)
使用上表,我试图以vala,valb和valc为列的形式获取值,不同的逗号分隔值为行。如下图所示:
我已经研究了https://lalitkumarb.wordpress.com/2014/12/02/split-comma-delimited-string-into-rows-in-oracle/和https://blogs.oracle.com/aramamoo/how-to-split-comma-separated-string-and-pass-to-in-clause-of-select-statement,但是由于我有更多的专栏文章,因此我似乎无法应用所描述的方法...
我需要执行此转换的原因是在查询中进一步在IN表达式中使用这些值。
答案 0 :(得分:2)
这应该起作用,而不管“高度”列为何。
BldgID BldgHt Device Total_count
108 28.0 760 4
104 36.0 758 2
41.0 758 6
104 45.0 758 2
答案 1 :(得分:1)
尝试一下:
with testdata(vala,valb,valc)
as(
select
'1,2,3,4' as vala,
'5,6,7,8' as valb,
'9,10,11' as valc
from dual)
,
main as (
select rownum rn,
regexp_substr(vala,'[^,]+', 1, level) data from
testdata
connect by regexp_substr(vala,'[^,]+', 1, level) is not null
),
sub as (
select rownum rn,
regexp_substr(valb,'[^,]+', 1, level)data from
testdata
connect by regexp_substr(valb,'[^,]+', 1, level) is not null
),
sub2 as (
select rownum rn,
regexp_substr(valc,'[^,]+', 1, level)data from
testdata
connect by regexp_substr(valc,'[^,]+', 1, level) is not null
)
select
main.data,
sub.data,
sub2.data
from
main
full outer join
sub on main.rn=sub.rn
full outer join
sub2 on main.rn=sub2.rn
答案 2 :(得分:0)
仅使用简单字符串函数(而不是慢速正则表达式)的解决方案,不需要任何连接,还可以处理多个输入行:
Oracle设置:
CREATE TABLE testdata (vala, valb, valc) AS
SELECT '1,2,3,4','5,6,7,8', '9,10,11' FROM DUAL UNION ALL
SELECT '12', '13,14,15,16', '' FROM DUAL;
查询:
WITH data ( vala, valb, valc, starta, startb, startc, enda, endb, endc, rn, idx ) AS (
SELECT vala,
valb,
valc,
1,
1,
1,
INSTR( vala, ',', 1 ),
INSTR( valb, ',', 1 ),
INSTR( valc, ',', 1 ),
ROWNUM,
1
FROM testdata
UNION ALL
SELECT vala,
valb,
valc,
CASE WHEN enda = 0 THEN 0 ELSE enda + 1 END,
CASE WHEN endb = 0 THEN 0 ELSE endb + 1 END,
CASE WHEN endc = 0 THEN 0 ELSE endc + 1 END,
CASE WHEN enda = 0 THEN 0 ELSE INSTR( vala, ',', enda + 1 ) END,
CASE WHEN endb = 0 THEN 0 ELSE INSTR( valb, ',', endb + 1 ) END,
CASE WHEN endc = 0 THEN 0 ELSE INSTR( valc, ',', endc + 1 ) END,
rn,
idx + 1
FROM data
WHERE enda > 0
OR endb > 0
OR endc > 0
)
SELECT CASE
WHEN starta = 0 THEN NULL
WHEN enda = 0 THEN SUBSTR( vala, starta )
ELSE SUBSTR( vala, starta, enda - starta )
END AS vala,
CASE
WHEN startb = 0 THEN NULL
WHEN endb = 0 THEN SUBSTR( valb, startb )
ELSE SUBSTR( valb, startb, endb - startb )
END AS valb,
CASE
WHEN startc = 0 THEN NULL
WHEN endc = 0 THEN SUBSTR( valc, startc )
ELSE SUBSTR( valc, startc, endc - startc )
END AS valc
FROM data
ORDER BY rn, idx;
输出:
VALA | VALB | VALC :--- | :--- | :--- 1 | 5 | 9 2 | 6 | 10 3 | 7 | 11 4 | 8 | null 12 | 13 | null null | 14 | null null | 15 | null null | 16 | null
db <>提琴here