Удалите дубликаты из уже агрегированного LISTAGG, используя LISTAGG - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть две таблицы ниже

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 19 c, поэтому я использую ниже запрос

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

1 Ответ

1 голос
/ 21 апреля 2020

Вы можете использовать приведенное ниже, чтобы отменить пометку и удалить дубликат, а затем снова переписать. Скрипт БД здесь

            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; 
...