将多个逗号分隔列转换为行

时间:2017-12-14 12:00:14

标签: oracle

我有一个Oracle表,它在许多列中包含逗号分隔值。例如:

Id  Column1 Column2
1   A,B,C   H
2   D,E     J,K
3   F       L,M,N

我想将所有列拆分成行,输出应为:

ID  Column1 Column2
1      A       H
1      B       H
1      C       H
2      D       J
2      D       K
2      E       J
2      E       K
3      F       L
3      F       M
3      F       N

我找到了一些使用regexp_substr和connect by的建议,但它只处理一个以逗号分隔值的列。我已经尝试过子查询方法,我将在内部查询中一次处理一个列,并将内部查询输出作为输入发送到外部查询,这需要更多时间,并且包含逗号分隔值的列更多。所以我不能使用子查询方法。

2 个答案:

答案 0 :(得分:0)

对于一列,您可以CROSS JOIN一个TABLE()集合表达式,其中包含使用分层查询将列值拆分为单独字符串的相关子查询。对于两列,您只需对第二列执行相同操作,CROSS JOIN负责确保column1中的每个分隔值与column2中的每个分隔值配对。

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name ( Id, Column1, Column2 ) AS
SELECT 1, 'A,B,C', 'H' FROM DUAL UNION ALL
SELECT 2, 'D,E',   'J,K' FROM DUAL UNION ALL
SELECT 3, 'F',     'L,M,N' FROM DUAL;

查询1

SELECT t.id,
       c1.COLUMN_VALUE AS c1,
       c2.COLUMN_VALUE AS c2
FROM   table_name t
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT REGEXP_SUBSTR( t.Column1, '[^,]+', 1, LEVEL )
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.Column1, '[^,]+' )
           ) AS SYS.ODCIVARCHAR2LIST
         )
       ) c1
       CROSS JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT REGEXP_SUBSTR( t.Column2, '[^,]+', 1, LEVEL )
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.Column2, '[^,]+' )
           ) AS SYS.ODCIVARCHAR2LIST
         )
       ) c2

<强> Results

| ID | C1 | C2 |
|----|----|----|
|  1 |  A |  H |
|  1 |  B |  H |
|  1 |  C |  H |
|  2 |  D |  J |
|  2 |  D |  K |
|  2 |  E |  J |
|  2 |  E |  K |
|  3 |  F |  L |
|  3 |  F |  M |
|  3 |  F |  N |

答案 1 :(得分:-1)

下面将介绍如何将逗号分隔的字符串转换为行。您可以使用此逻辑来满足您的需求。

select regexp_substr('a,b,c,v,f', '[^,]+',1,level)
from dual 
connect by level <= regexp_count('a,b,c,v,f', ',') + 1;