多个逗号分隔的列表到列

时间:2019-08-29 06:50:39

标签: sql oracle split

我正在尝试将一列中用逗号分隔的列表拆分为不同的行。例如:

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为列的形式获取值,不同的逗号分隔值为行。如下图所示:

Expected result

我已经研究了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表达式中使用这些值。

3 个答案:

答案 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