Évitez plusieurs agrégats imbriqués dans les requêtes PostgreSQL
Plusieurs appels array_agg() dans une seule requête peuvent entraîner des résultats inattendus, comme le montre la exemple fourni. Ce problème découle de la jointure de tables comportant plusieurs lignes, créant ainsi un produit cartésien. Pour remédier à ce problème, envisagez les stratégies suivantes :
Agréger d'abord, rejoindre plus tard
Agréger les données de chaque table séparément dans une sous-requête avant de les joindre. Cela garantit que vous agrégez sur un ensemble unique de lignes :
SELECT e.id, e.name, e.age, e.streets, array_agg(wd.day) AS days FROM ( SELECT e.id, e.name, e.age, array_agg(ad.street) AS streets FROM employees e JOIN address ad ON ad.employeeid = e.id GROUP BY e.id ) e JOIN workingdays wd ON wd.employeeid = e.id GROUP BY e.id, e.name, e.age;
Sous-requêtes corrélées ou JOIN LATERAL
Utilisez des sous-requêtes corrélées ou JOIN LATERAL pour agréger les données de chaque ligne. individuellement, permettant des filtres sélectifs :
Corrélés Sous-requêtes :
SELECT name, age , (SELECT array_agg(street) FROM address WHERE employeeid = e.id) AS streets , (SELECT array_agg(day) FROM workingdays WHERE employeeid = e.id) AS days FROM employees e WHERE e.namer = 'peter';
JOIN LATERAL :
SELECT e.name, e.age, a.streets, w.days FROM employees e LEFT JOIN LATERAL ( SELECT array_agg(street) AS streets FROM address WHERE employeeid = e.id GROUP BY 1 ) a ON true LEFT JOIN LATERAL ( SELECT array_agg(day) AS days FROM workingdays WHERE employeeid = e.id GROUP BY 1 ) w ON true WHERE e.name = 'peter';
Ces méthodes évitent la duplication inutile de lignes et fournissent les résultats d'agrégation de tableaux souhaités.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!