Maison >base de données >tutoriel mysql >Comment éviter les lignes en double lors de l'utilisation de plusieurs agrégats de tableaux dans une requête SQL ?

Comment éviter les lignes en double lors de l'utilisation de plusieurs agrégats de tableaux dans une requête SQL ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-30 07:34:09333parcourir

How to Avoid Duplicate Rows When Using Multiple Array Aggregates in a SQL Query?

Évitez plusieurs agrégats de tableaux dans une requête

Dans votre requête, vous essayez d'utiliser plusieurs fonctions array_agg() dans une seule requête pour récupérer des tableaux de différentes tables. Cependant, cette approche conduit à des lignes en double et à des résultats déformés.

Le problème

Lorsque vous effectuez plusieurs jointures et fonctions d'agrégation, l'ensemble de résultats peut être gonflé de doublons. Dans votre cas, joindre les tables d'adresses et de jours ouvrables crée plusieurs lignes pour chaque employé, ce qui entraîne des entrées en double dans les tableaux agrégés.

Solution : agrégation et jointures séparées

Pour résoudre ce problème, il est recommandé de séparer l'opération d'agrégation du processus de jointure. Considérez les approches suivantes :

Agréger d'abord, rejoindre plus tard :

Tout d'abord, agrégez les données de chaque table séparément à l'aide de sous-requêtes. Ensuite, joignez les résultats agrégés en fonction de la clé primaire ou d'une colonne commune :

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 :

Pour un filtrage sélectif des données, pensez en utilisant des sous-requêtes corrélées ou des jointures LATÉRALES dans PostgreSQL :

Corrélé 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 (PostgreSQL 9.3 ou version ultérieure) :

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 approches garantissent que les tableaux agrégés sont correctement associés aux employés correspondants, fournissant les résultats attendus.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn