【问题标题】:Remove duplicates from an already aggregated LISTAGG using LISTAGG使用 LISTAGG 从已经聚合的 LISTAGG 中删除重复项
【发布时间】:2020-04-21 09:19:27
【问题描述】:

我有下面两张表

SELECT * FROM TABLE_ONE  
UNION
SELECT * FROM TABLE_TWO

结果

ID|PRODUCTS   |TOTAL_AMOUNT|
--|-----------|------------|
 1|TABLE|CHAIR|           8|
 1|TABLE|TV   |          12|
 2|CUP        |          13|
 2|PLATE      |          14|

现在我想做一个 listagg 并删除 oracle 19c 上的重复项,因此我使用以下查询

SELECT ID, listagg(DISTINCT PRODUCTS, '|') within group (order by PRODUCTS)  PRODUCTS, SUM(AMOUNT) FROM (    
SELECT * FROM TABLE_ONE  
UNION
SELECT * FROM TABLE_TWO
) GROUP BY ID

我得到的结果是

ID|PRODUCTS            |SUM(TOTAL_AMOUNT)|
--|--------------------|-----------------|
 1|TABLE|CHAIR|TABLE|TV|               20|
 2|CUP|PLATE           |               27|

我想要的结果是

ID|PRODUCTS            |SUM(TOTAL_AMOUNT)|
--|--------------------|-----------------|
 1|TABLE|CHAIR|TV      |               20|
 2|CUP|PLATE           |               27|

db <> fiddle 中的测试数据虽然是oracle18c,但在我使用oracle 19c 的 listagg 中不支持 distinct

【问题讨论】:

  • 问题是'TABLE|CHAIR' 是一个字符串,而'TABLE|TV' 是另一个字符串。如果您对单独的部分感兴趣,请将它们分开存放。 IE。您需要包含单个产品的子表。
  • @ThorstenKettner 现在这就是我问这个问题的原因,我如何在合并两者后删除重复项。
  • 我是说你没有正确使用你的 DBMS。建立一个关系数据库。这意味着没有像'TABLE|CHAIR' 这样的连接字符串。假设您的桌子是订单。然后,您需要另一个表用于产品和第三个表链接产品和订单。
  • @ThorstenKettner 我明白了。不过,我正在根据给定的用例汇总报告,以供 3rd 方客户用于营销。我们已经有了那个关系数据库。 table_one 是第一天的报告,我想使用简单的选择查询轻松合并日期。
  • 好的。这些表代表聚合结果,因此包含连接的字符串。现在,您想在此基础上构建并再次取消连接字符串。可以使用REGEXP_REPLACE 检测和删除连接字符串中的重复项,但我想我宁愿编写一个 PL/SQL 函数来拆分字符串并连接其不同的部分。

标签: sql oracle oracle12c listagg oracle19c


【解决方案1】:

您可以使用以下命令取消列出并删除重复项,然后再次列出。The DB Fiddle here

            WITH data
         AS (SELECT id,
                    Listagg(products, '|')
                      within GROUP (ORDER BY products) PRODUCTS,
                    SUM(amount)                        SUM_AMT
             FROM   (SELECT *
                     FROM   table_one
                     UNION
                     SELECT *
                     FROM   table_two)
             GROUP  BY id),
         d2
         AS (SELECT DISTINCT id,
                             Regexp_substr(products, '[^|]+', 1, column_value) AS
                             products,
                             sum_amt
             FROM   data
                    cross join TABLE(Cast(MULTISET (SELECT LEVEL
                                              FROM   dual
                                              CONNECT BY LEVEL <=
                                              Regexp_count(products,
                                              '[^|]+'))
                                                       AS
    sys.ODCINUMBERLIST)))
    SELECT id,
           Listagg(products, '|')
             within GROUP (ORDER BY id) PRODUCTS,
           sum_amt
    FROM   d2
    GROUP  BY id,
              sum_amt; 

【讨论】:

    猜你喜欢
    • 2022-01-06
    • 2018-11-28
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2020-04-19
    • 2012-07-22
    • 2021-08-04
    • 1970-01-01
    相关资源
    最近更新 更多