累积字符串连接

时间:2016-02-01 18:51:55

标签: sql oracle

我有一个要求,我必须以累积连接方式显示数据,就像按组运行总计一样。

示例数据

Col1    Col2
1       a
1       b
2       c 
2       d
2       e

预期产出:

Col1    Col2
1       a
1       b,a
2       c 
2       d,c
2       e,d,c

连接需要由Col1细分。有关如何通过Oracle SQL获得此结果的任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

尝试:

WITH d AS (
    select col1, col2, 
           row_number() over (partition by col1 order by col2) as x
    from tab_le
),
d1( col1, col2, x, col22) as (
  SELECT col1, col2, x, col2 col22 FROM d WHERE x = 1
  UNION ALL
  SELECT d.col1, d.col2, d.x, d.col2 || ',' || d1.col22
  FROM d
  JOIN d1 ON (d.col1 = d1.col1 AND d.x = d1.x + 1)
)
SELECT * FROM d1
order by 1,2;

答案 1 :(得分:1)

我不确定您是否可以使用listagg执行此操作,因为它似乎不支持窗口条款。如果您使用的是11g或更高,则可以使用recursive subquery factoring来获得结果。

with your_table (col1, col2) as (
            select 1, 'a' from dual
  union all select 1, 'b' from dual
  union all select 2, 'c' from dual
  union all select 2, 'd' from dual
  union all select 2, 'e' from dual
), t as (
  select col1, col2, row_number() over (partition by col1 order by col2) as rn
  from your_table
), r (col1, col2, rn) as (
  select col1, col2, rn
  from t
  where rn = 1
  union all
  select r.col1, t.col2 ||','|| r.col2, t.rn
  from r
  join t on t.col1 = r.col1 and t.rn = r.rn + 1
)
select col1, col2
from r
order by col1, rn;

     COL1 COL2               
---------- --------------------
         1 a                   
         1 b,a                 
         2 c                   
         2 d,c                 
         2 e,d,c               

your_table CTE只是为了模仿你的基础数据。 t CTE添加row_number()分析列以提供下一部分的序列。有趣的部分是r递归CTE。锚成员从第一行开始(根据前一个CTE的rn)。然后,递归成员为rn找到下一行(根据col1),并为此将当前col2与前一行连接,这可能本身已经是一个连接

答案 2 :(得分:1)

假设您需要订购的方式,这可以是基于Hierarchical Queries的解决方案:

with test as
(
    select 1 as col1,      'a' as col2 from dual union all
    select 1 as col1,      'b' as col2 from dual union all
    select 2 as col1,      'c' as col2 from dual union all
    select 2 as col1,      'd' as col2 from dual union all
    select 2 as col1,      'e' as col2 from dual
 )
select col1, col2
from (
        select col1 AS col1, sys_connect_by_path(col2, ',') AS col2, connect_by_isleaf leaf
        from (
                select row_number() over (order by col1 asc, col2 desc) as num, col1, col2
                from test
             )
        connect by nocycle prior col1 = col1 and prior num = num -1
)
where leaf = 1
order by col1, col2