Как агрегировать и объединять строки одновременно в Oracle? - PullRequest
0 голосов
/ 01 октября 2018

У меня есть данные, которые выглядят так:

Customer      Product     Amount
   A           Table        500  
   A           Table        300
   A           Chair        100
   B           Rug           50
   B           Chair        200

И я пытаюсь получить результат, похожий на этот:

Customer      Product        Amount
   A           Table, Chair    900  
   B           Rug, Chair      250

В MSSQL я мог бы использовать для XML PATH('') и легко добраться туда.Я не так разбираюсь в Oracle.Я попытался использовать LISTAGG, и вот что я получаю:

Customer      Product                 Amount
   A           Table,Table,Chair       1150  
   B           Rug, Chair              1150

Итак, я получаю дубликаты в строке Product, и суммы как-то одинаковы.Рассматривая некоторые похожие вопросы здесь, я не могу найти, как сделать и совокупный, и отдельный листаг вместе.Вот моя попытка:

Select
 Customer
,sum(Amount) as "Amount"
,LISTAGG(Product, ', ') WITHIN GROUP(Order by CUSTOMER) as "TestingThis"
From
(Select 
  A.Customer
 ,B.Product
 ,B.Amount
 ,Row_Number() over (Partition by A.Customer, B.Product order by A.Customer) as rn
  From
  CustomerTable A
  left join ProductTable B
  on A.ID = B.ID
  Group by
  A.Customer
 ,B.Product
 ,B.Amount
)
 where rn = 1
 Group by Customer

Это будет немного ближе и приведет к следующему:

Customer      Product        Amount
   A           Table, Chair    600
   B           Rug, Chair      250

Обратите внимание, что это суммируется только когда rn = 1, поэтому он пропускает остальныеСумма.

Использование Oracle 11g, так что если у них есть какая-то необычная особенность LISTAGG в новых версиях, это мне не поможет.

Переход с MSSQL на PLSQL болезнен.Это было бы так легко сделать в MSSQL.Я не понимаю, как LISTAGG мог бы / когда-либо быть полезен, когда не мог легко получить различные значения?

Ближайшие решения, которые я нашел здесь, не учитывают другую агрегацию, такую ​​как сумма в дополнение котчетливый LISTAGG.Они просто говорят: «Если вам нужно сделать еще одну агрегацию с LISTAGG, тогда это сложно».

Ну, это именно то, что мне нужно.(

1 Ответ

0 голосов
/ 01 октября 2018

Будет ли это делать?

SQL> with test (customer, product, amount) as
  2    (select 'a', 'table', 500 from dual union all
  3     select 'a', 'table', 300 from dual union all
  4     select 'a', 'chair', 100 from dual union all
  5     select 'b', 'rug'  , 50  from dual union all
  6     select 'b', 'chair', 200 from dual
  7    )
  8  select customer,
  9    listagg (product, ', ') within group (order by null) product,
 10    sum(sum_amount) amount
 11  from (select customer, product, sum(amount) sum_amount
 12        from test
 13        group by customer, product
 14       )
 15  group by customer
 16  order by customer;

C PRODUCT                  AMOUNT
- -------------------- ----------
a chair, table                900
b chair, rug                  250

SQL>
...