Maison >base de données >tutoriel mysql >Pourquoi ma requête PostgreSQL LEFT JOIN multiplie-t-elle les comptes au lieu de les conserver ?
PostgreSQL LEFT JOIN : multiplication inattendue du nombre de lignes
Une requête PostgreSQL 9.1 utilisant plusieurs LEFT JOIN a multiplié de manière inattendue le nombre de lignes au lieu de les conserver. La requête visait à récupérer les identifiants des utilisateurs, les soldes des comptes, le nombre de visites à l'épicerie et le nombre de visites au marché aux poissons. La requête défectueuse a entraîné des décomptes incorrects, affichant des valeurs répétées au lieu des décomptes réels.
Ce problème provient de l'ordre de traitement JOIN de gauche à droite de PostgreSQL. Les JOIN suivantes répliquent les lignes des jointures précédentes, ce qui entraîne un comptage de l'inflation. Par exemple, s'il y avait 3 visites à l'épicerie et 12 visites au marché aux poissons, le résultat affichait à tort 12 entrées pour chacune au lieu des 3 et 12 attendues.
La solution consiste à pré-agréger le nombre de visites avant de rejoindre. Cela évite le problème de multiplication de lignes. La requête corrigée est :
<code class="language-sql">SELECT u.id, u.account_balance, g.grocery_visits, f.fishmarket_visits FROM users u LEFT JOIN ( SELECT user_id, count(*) AS grocery_visits FROM grocery GROUP BY user_id ) g ON g.user_id = u.id LEFT JOIN ( SELECT user_id, count(*) AS fishmarket_visits FROM fishmarket GROUP BY user_id ) f ON f.user_id = u.id ORDER BY u.id;</code>
Cette requête révisée renvoie correctement les décomptes individuels de visites à l'épicerie et à la poissonnerie par utilisateur, résolvant ainsi le problème de multiplication. Par exemple, si un utilisateur a effectué trois visites à l'épicerie et quatre visites au marché aux poissons, le résultat reflète cela avec précision, évitant ainsi la répétition erronée observée dans la requête d'origine.
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!