【问题标题】:Oracle concatenation of columns with comma [duplicate]Oracle用逗号连接列[重复]
【发布时间】:2012-10-19 23:57:41
【问题描述】:

可能重复:
How can I combine multiple rows into a comma-delimited list in Oracle?

有人可以告诉我如何实现以下目标吗?

表:

efforts_id        cycle_name      release_name 
123               quarter         march 
123               half            april 
123               full            april
124               quarter         may

我的预期输出:

efforts_id        cycle_name            release_name 
123               quarter,half,full     march,april
124               quarter               may

我是 oracle 的初学者,所以不知道该怎么做。任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: sql database oracle concatenation string-aggregation


    【解决方案1】:

    您将需要使用LISTAGG() 来执行此任务。其他答案不会删除任何重复值,要删除重复值,您可以使用类似于以下内容的内容:

    select c.efforts_id, 
      c.cycle_name,
      listagg(r.release_name, ', ') within group (order by c.efforts_id) as release_name
    from
    (
      select efforts_id,
        listagg(cycle_name, ', ') within group (order by efforts_id) as cycle_name
      from yourtable
      group by efforts_id
    ) c
    inner join
    (
      select distinct efforts_id, release_name
      from yourtable
    ) r
      on c.efforts_id = r.efforts_id
    group by c.efforts_id, c.cycle_name
    

    SQL Fiddle with Demo

    【讨论】:

    • @Jeevan 不客气,可能可以使用with 子句而不是子选择来稍微清理一下,以您的偏好为准
    • 嗯好的..我不知道该怎么做。 (我是甲骨文的新手..全新的:))。我现在会接受你的回答。
    • 需要帮助..我想对 cycle_name 和 release_name 列进行重复删除..我尝试了一些东西,但似乎没有用。 sqlfiddle.com/#!4/430ee/15请帮忙
    • @Jeevan 请查看此演示 -- sqlfiddle.com/#!4/430ee/22
    【解决方案2】:

    如果您有 Oracle 11g R2,那么 LISTAGG 是首选方式:

    SELECT efforts_id,
        LISTAGG(cycle_name) WITHIN GROUP(ORDER BY cycle_name),
        LISTAGG(release_name) WITHIN GROUP(ORDER BY cycle_name)
    FROM MY_TABLE
    GROUP BY efforts_id
    

    如果没有,this article 会显示替代方法。

    【讨论】:

      【解决方案3】:

      您需要的是“字符串聚合”。 Tim Hall 的优秀网站显示了您拥有的替代方案,具体取决于您拥有的 Oracle 的确切版本:http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php

      在 11gR2(撰写本文时为当前版本)中,您应该使用 listagg 函数:

      select
        efforts_id,
        listagg(cycle_name, ',') within group (order by cycle_name) as cycle_name,
        listagg(release_name, ',') within group (order by release_name) as release_name
      from my_table
      group by efforts_id;
      

      注意,Oracle 不支持使用 wm_concat 函数...

      【讨论】:

      • +1,记住 listagg 被限制为 4000 字节。
      • 因为它是 varchar,而不是 clob。有传言说,在 Oracle 12c 中——大约在今年年底——将在数据库中拥有高达 32767 的 varchars,就像在 PL/SQL 中一样......
      • @ErkanHaspulat 4000 字符,当然?!
      • 谢谢...只是一个问题..输出是这样的。 Release _name for 123 is march,april,april...如何避免重复的4月?
      • 您可以在汇总之前distinct您的数据。您可能需要一个子查询或一个 with 子句。
      【解决方案4】:

      通过WM_concat 函数(当然还有GROUP BY

      SELECT efforts_id, wm_concat(cycle_name), wm_concat(release_name)
      FROM MY_TABLE
      GROUP BY efforts_id
      

      嗯,刚找到这个:

      请注意,WM_CONCATOracle 未记录且不受支持的,这意味着它不应在生产系统中使用 LISTAGG 函数可以产生与 WM_CONCAT 相同的输出,Oracle 已记录并支持该函数。

      【讨论】:

        猜你喜欢
        • 2020-09-14
        • 2013-08-11
        • 1970-01-01
        • 2021-09-05
        • 1970-01-01
        • 2016-03-13
        • 2012-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多