Comprendre le nombre de visites inexactes avec plusieurs SQL LEFT JOINs
Cet article examine un problème de requête SQL courant : obtenir un nombre de visites incorrect lors de l'utilisation de plusieurs LEFT JOIN
opérations. L'objectif est de récupérer les données des utilisateurs, notamment le solde du compte, les visites à l'épicerie et les visites au marché aux poissons. Une requête naïve produit souvent des résultats gonflés (par exemple, "1", "12", "12").
Le problème vient de l'exécution de gauche à droite des LEFT JOIN
s. Chaque jointure suivante multiplie le nombre de lignes s'il existe plusieurs entrées correspondantes dans les tables jointes. Par exemple, joindre trois tables d'épicerie à un utilisateur donne trois lignes. Une jointure ultérieure avec quatre tables de marché aux poissons étend ensuite ce nombre à douze lignes, ce qui entraîne un décompte de visites inexact.
La solution : pré-agrégation avec des sous-requêtes
La solution consiste à pré-agréger le nombre de visites pour chaque table avant de les joindre à la table users
. Cela évite le problème de multiplication de lignes. La requête corrigée utilise des sous-requêtes pour y parvenir :
<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>
Gestion des valeurs manquantes avec COALESCE
Pour gérer avec élégance les cas où un utilisateur n'a aucune visite à un emplacement particulier, la fonction COALESCE
peut remplacer les valeurs NULL
par 0 (ou toute autre valeur souhaitée) :
<code class="language-sql">SELECT u.id, u.account_balance, COALESCE(g.grocery_visits, 0) AS grocery_visits, COALESCE(f.fishmarket_visits, 0) AS 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 améliorée reflète avec précision le nombre de visites à l'épicerie et au marché aux poissons pour chaque utilisateur. En pré-agrégeant les données, nous évitons les pièges des LEFT JOIN
en cascade et garantissons des résultats précis.
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!