Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-String-Aggregation

Ich gehe davon aus, dass die PRIORITY Spalte ist immer 1, wenn es ein "Hauptprodukt" gibt, und niemals 1 zu anderen Zeiten. Aus Ihren Daten geht auch hervor, dass jeder Kunde nur ein „Hauptprodukt“ hat. Ich gehe mal davon aus, dass das stimmt. Wenn dies nicht der Fall ist, sollten Sie eine weitere Spalte zur Unterscheidung von Produktgruppen haben. Sie können dies einfach unten hinzufügen.

Die komplizierte/effiziente Antwort könnte wie folgt lauten:

select customer
     , max(product) keep (dense_rank first order by priority) as main_product
     , listagg(case when priority = 2 then product end, ', ')
         within group (order by product) as sub_product
  from products
 group by customer

SQL-Fiddle

Pro Kunde das PRODUCT Spalte geht davon aus, dass jeder Kunde ein Hauptprodukt hat, und erhält dann das erste Produkt in der Reihenfolge nach Priorität. Die zweite Spalte übernimmt nur dort, wo die Priorität 2 ist, und verwendet die Zeichenfolgenverkettungsfunktion LISTAGG(), um Ihre Werte miteinander zu verketten.

Ich kann den Blogbeitrag von Rob van Wijk über die KEEP-Klausel sehr empfehlen.

Eine Standard-SQL-Lösung würde wie folgt aussehen:

select a.customer, a.product as main_product
     , listagg(b.product, ', ') within group (order by b.product) as sub_product
  from products a
  join products b
    on a.customer = b.customer
 where a.priority = 1
   and b.priority = 2
 group by a.customer, a.product

d.h. alles finden, was eine Priorität von 1 hat, verwenden Sie dies, um Ihre zwei Zeilen zu generieren und dann alles mit einer Priorität von 2 zu erhalten und diese zu aggregieren.