Oracle
 sql >> Base de données >  >> RDS >> Oracle

Agrégation de chaînes Oracle

Je vais supposer que la PRIORITY la colonne est toujours 1 lorsqu'il y a un "produit principal" et jamais 1 à tout autre moment. D'après vos données, il semble également que chaque client n'a qu'un seul produit "principal". Je vais supposer que c'est vrai. Si ce n'est pas le cas, vous devriez avoir une autre colonne pour distinguer les groupes de produits. Vous pouvez simplement l'ajouter ci-dessous.

La réponse compliquée/efficace peut être la suivante :

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

Violon SQL

Par client, le PRODUCT La colonne suppose que chaque client a un produit principal, puis obtient le premier produit par ordre de priorité. La deuxième colonne ne prend que là où la priorité est 2 et utilise la fonction de concaténation de chaînes LISTAGG() pour concaténer vos valeurs ensemble.

Je recommanderais vivement le billet de blog de Rob van Wijk sur la clause KEEP.

Une solution SQL plus standard ressemblerait à ceci :

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

c'est-à-dire trouver tout ce qui a une priorité de 1, l'utiliser pour générer vos deux lignes, puis obtenir tout ce qui a une priorité de 2 et les agréger.