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

Agréger une seule colonne dans une requête avec plusieurs colonnes

Requête simple

Cela peut être beaucoup plus simple avec PostgreSQL 9.1 ou version ultérieure . Comme expliqué dans cette réponse étroitement liée :

  • PGError :ERREUR :agrégats non autorisés dans la clause WHERE sur une requête AR d'un objet et de ses objets has_many

Il suffit de GROUP BY la clé primaire d'un tableau. Depuis :

foo1 est une clé primaire

.. vous pouvez simplifier votre exemple en :

SELECT foo1, foo2, foo3, foo4, foo5, foo6, string_agg(aggregated_field, ', ')
FROM   tbl1
GROUP  BY 1
ORDER  BY foo7, foo8;  -- have to be spelled out, since not in select list!

Requête avec plusieurs tables

Cependant, puisque vous avez :

beaucoup plus de champs et de LEFT JOIN, la partie importante est que tous ces champs ont une relation de 1 à 1 ou de 1 à 0 sauf un champ qui est de 1 à n que je veux agréger

.. il devrait être plus rapide et plus simple de regrouper d'abord, rejoindre plus tard :

SELECT t1.foo1, t1.foo2, ...
     , t2.bar1, t2.bar2, ...
     , a.aggregated_col 
FROM   tbl1 t1
LEFT   JOIN tbl2 t2 ON ...
...
LEFT   JOIN (
   SELECT some_id, string_agg(agg_col, ', ') AS aggregated_col
   FROM   agg_tbl a ON ...
   GROUP  BY some_id
   ) a ON a.some_id = ?.some_id
ORDER  BY ...

De cette façon, la grande partie de votre requête n'a pas du tout besoin d'agrégation.

J'ai récemment fourni un cas de test dans un SQL Fiddle pour prouver le point dans cette réponse connexe :

  • PostgreSQL – Trier par un tableau

Puisque vous faites référence à cette réponse connexe :Non, DISTINCT ne va pas aider du tout dans ce cas.