Maison >base de données >tutoriel mysql >Comment éviter les données redondantes lors de la combinaison de plusieurs appels `array_agg()` dans une seule requête SQL ?
Combinaison de plusieurs appels array_agg() dans une seule requête
Dans votre requête, vous rencontrez un problème où plusieurs appels array_agg() renvoient des éléments redondants données. La présence de lignes en double en raison de plusieurs jointures entraîne des résultats indésirables. Pour résoudre ce problème, nous pouvons explorer plusieurs approches qui évitent la multiplication des lignes dès le départ.
Solution 1 : Agréger d'abord, rejoindre plus tard
Une méthode efficace consiste à agréger les données dans les sous-requêtes avant d’effectuer les jointures. Cela garantit que chaque enregistrement d'employé est unique, empêchant ainsi la multiplication des lignes. La requête modifiée ressemblerait à ceci :
SELECT e.id, e.name, e.age, ad.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 -- PK covers whole row ) e JOIN workingdays wd ON wd.employeeid = e.id GROUP BY e.id, e.name, e.age;
Solution 2 : Sous-requêtes corrélées / JOIN LATERAL
Une autre approche consiste à utiliser des sous-requêtes corrélées ou JOIN LATERAL dans PostgreSQL 9.3 ou plus tard. Cette technique permet de récupérer les données agrégées pour chaque collaborateur au sein de la requête principale. Les requêtes modifiées seraient :
Sous-requêtes corrélées :
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'; -- very selective
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'; -- very selective
Conclusion
En mettant en œuvre ces approches, vous pouvez éviter la multiplication des lignes et obtenir le résultat souhaité, qui est un tableau d'adresses et un tableau de jours de travail pour chaque employé. Ces solutions garantissent que les données sont agrégées de manière appropriée et fusionnées correctement, éliminant ainsi le besoin de filtrage ou de post-traitement supplémentaire.
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!