【问题标题】:Gradually aggregating a string column in Oracle SQL在 Oracle SQL 中逐渐聚合一个字符串列
【发布时间】:2019-12-10 11:32:03
【问题描述】:

我想在 Oracle sql 中逐步聚合一个字符串列。

从此表中:

col_1 | col_2
-------------
1     | A
1     | B
1     | C
2     | C
2     | D

到:

col_1 | col_2
-------------
1     | A
1     | A,B
1     | A,B,C
2     | C
2     | C,D

我尝试了LISTAGG,但由于group by,它不会返回所有行。我的表中有大约 200 万行。

【问题讨论】:

  • 如前所述,问题不是确定性的。你怎么知道,从输入,输出应该显示'A',然后是'A,B',然后是'A,B,C'?是什么让值为 'A' 的行成为 col_1 = 1first 行?或者你实际上有一个额外的列来定义你的行的顺序?
  • 另外,output 字符串的最大长度是否可以提前保证?如果没有,您将需要在输出中使用CLOB - 例如,排除使用LISTAGG()(尽管您已经选择了“正确答案”)。
  • 顺便说一句,listagg() 不适用于标签之一的oracle10g。例如没有listagg() 的解决方案更通用。
  • @mathguy 这是一个很好的观点。有一个索引 col 定义了顺序。我可以提前找到输出字符串的最大长度。
  • @BarbarosÖzhan 这是一个错误。我在找 12。

标签: sql oracle oracle11g oracle12c


【解决方案1】:

Oracle 不支持使用单个 listagg() 表达式累积字符串连接。但是,您可以使用子查询。

请注意:SQL 表表示 无序 集。你似乎有一个命令。以下代码添加了一个排序列:

with t as (
      select 1 as id, 1 as x, 'A' as y from dual union all
      select 2, 1 as x, 'B' as y from dual union all
      select 3, 1 as x, 'C' as y from dual union all
      select 4, 2 as x, 'C' as y from dual union all
      select 5, 2 as x, 'D' as y from dual
     )
select t.*,
       (select listagg(t2.y, ',') within group (order by t2.id)
        from t t2
        where t2.x = t.x and t2.id <= t.id
       ) 
from t;

【讨论】:

  • 谢谢。我确实需要订购。我不确定如何处理 200 万行。尽管示例表只有五行,但我有一个包含 200 万行的实际表。
  • @user11871120 。 . .您可以只运行查询。表中的行数无关紧要。
  • 表中的行数显然确实很重要(当然col_1 中具有相同值的行数),因为listagg() 仅适用于@987654325 @,而不是 CLOB。在listagg() 处抛出太多值会出错。
【解决方案2】:

分层查询选项如下所示:

SQL> with t as (
  2        select 1 as id, 1 as x, 'A' as y from dual union all
  3        select 2,       1 as x, 'B' as y from dual union all
  4        select 3,       1 as x, 'C' as y from dual union all
  5        select 4,       2 as x, 'C' as y from dual union all
  6        select 5,       2 as x, 'D' as y from dual
  7       )
  8  select x,
  9         ltrim(sys_connect_by_path(y, ','), ',') result
 10  from (select x,
 11               y,
 12              row_number() over (partition by x order by y) rn
 13        from t
 14       )
 15  start with rn = 1
 16  connect by prior rn = rn - 1 and prior x = x;

         X RESULT
---------- --------------------
         1 A
         1 A,B
         1 A,B,C
         2 C
         2 C,D

SQL>

【讨论】:

    猜你喜欢
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 2018-11-30
    • 2013-10-28
    • 1970-01-01
    • 2020-11-09
    相关资源
    最近更新 更多