使用 LISTAGG 从已聚合的 LISTAGG 中删除重复项

Remove duplicates from an already aggregated LISTAGG using LISTAGG

我有下面两个表

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,但不支持listagg中的distinct我正在使用oracle 19c

您可以使用以下方法取消列表并删除重复项,然后再次列表。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;