Maison >base de données >tutoriel mysql >Comment puis-je éviter les résultats SUM multipliés lors de la jointure de tables dans MySQL ?

Comment puis-je éviter les résultats SUM multipliés lors de la jointure de tables dans MySQL ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-19 14:32:09972parcourir

How Can I Avoid Multiplied SUM Results When Joining Tables in MySQL?

Éviter les résultats SUM multipliés dans les jointures MySQL

Les jointures MySQL, lorsqu'elles sont combinées avec des agrégations SUM, produisent souvent des résultats inexacts et gonflés en raison de l'effet produit cartésien. Plusieurs jointures peuvent entraîner une duplication de lignes, gonflant les valeurs SUM. La solution consiste à pré-agréger les données à l'aide de sous-requêtes.

Stratégie efficace : sous-requêtes pour une agrégation précise

Pour éviter les SUM gonflés, effectuez les agrégations avant de joindre les tables. Ceci est réalisé grâce à des sous-requêtes qui regroupent et additionnent les données de manière indépendante, puis rejoignent les résultats agrégés.

Exemple de requête et explication :

Cette requête montre comment joindre correctement des tables tout en utilisant des agrégations SUM :

<code class="language-sql">SELECT 
    i.last_name, 
    i.first_name, 
    DATE_FORMAT(LEAST(m.mil_date, t.tm_date), '%m/%d/%y') AS dates, 
    t.total, 
    m.minutes
FROM 
    bhds_teachers AS i
LEFT JOIN (
    SELECT 
        ds_id, 
        YEARWEEK(mil_date) AS week, 
        MIN(mil_date) AS mil_date, 
        SUM(drive_time) AS minutes
    FROM 
        bhds_mileage
    WHERE 
        mil_date BETWEEN '2016-04-11' AND '2016-04-30'
        AND ds_id = 5
    GROUP BY 
        ds_id, week
) AS m ON m.ds_id = i.ds_id
LEFT JOIN (
    SELECT 
        ds_id, 
        YEARWEEK(tm_date) AS week, 
        MIN(tm_date) AS tm_date, 
        SUM(tm_hours) AS total
    FROM 
        bhds_timecard
    WHERE 
        tm_date BETWEEN '2016-04-11' AND '2016-04-30'
        AND ds_id = 5
    GROUP BY 
        ds_id, week
) AS t ON t.ds_id = i.ds_id AND t.week = m.week;</code>

Les sous-requêtes (m et t) calculent indépendamment les sommes de drive_time et tm_hours, respectivement, en les regroupant par ds_id et week. Ces résultats agrégés sont ensuite joints à bhds_teachers (alias i) en utilisant les numéros ds_id et week correspondants. LEAST() sélectionne la date la plus ancienne parmi les deux tables agrégées. Cette méthode évite le problème de multiplication inhérent à la jointure avant la sommation.

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