Maison > base de données > tutoriel mysql > Comment éviter les valeurs SUM multipliées lors de la jointure de tables avec des fonctions d'agrégation dans MySQL ?

Comment éviter les valeurs SUM multipliées lors de la jointure de tables avec des fonctions d'agrégation dans MySQL ?

Patricia Arquette
Libérer: 2025-01-19 14:26:11
original
377 Les gens l'ont consulté

How to Avoid Multiplied SUM Values When Joining Tables with Aggregate Functions in MySQL?

Conseils pour éviter la multiplication des valeurs SUM lors de l'utilisation de fonctions d'agrégation pour joindre des tables dans MySQL

Lors de la combinaison de plusieurs opérations de jointure dans une requête MySQL, l'utilisation de fonctions d'agrégation telles que SUM peut conduire à des résultats inattendus. En effet, le produit cartésien de ligne de la table de jointure multiplie les résultats additionnés, ce qui entraîne des résultats inexacts.

Supposons qu'il existe un exemple dans lequel deux requêtes sont initialement utilisées pour récupérer les valeurs SUM de différentes tables. La requête 1 calcule le temps de conduite total pour un employé spécifique pendant une plage de dates spécifique, tandis que la requête 2 calcule le temps de travail total pour le même employé pendant la même période.

Essayer de combiner ces requêtes en une seule requête de jointure entraînera des sommes incorrectes. En effet, l'opération JOIN crée le produit cartésien des lignes du tableau bhds_timecard et bhds_mileage. En conséquence, les valeurs SUM pour le temps de conduite et le temps de travail sont multipliées par le nombre de lignes correspondantes dans chaque tableau.

Pour résoudre ce problème, vous pouvez utiliser une sous-requête pour calculer la valeur SUM avant de joindre les tables. En déplaçant l'opération SUM dans une sous-requête distincte, vous pouvez empêcher le produit cartésien et obtenir des résultats précis.

Ce qui suit est une requête améliorée à l'aide de sous-requêtes :

<code class="language-sql">SELECT last_name, first_name, DATE_FORMAT(LEAST(mil_date, tm_date), '%m/%d/%y') AS dates, 
       total, 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 bhds_mileage.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 bhds_timecard.ds_id = 5
    GROUP BY ds_id, week
) AS t ON t.ds_id = i.ds_id AND t.week = m.week;</code>
Copier après la connexion

Dans cette requête :

  • Sous-requête m Calcule le temps de conduite total regroupé par numéro d'employé et par semaine.
  • Sous-requête t Calcule le total des heures travaillées regroupées par numéro d'employé et par semaine.
  • La requête principale rejoint la table bhds_teachers avec les sous-requêtes m et t.

En conséquence, la requête récupère le nom, le prénom, la date, le temps total de travail et le temps total de conduite du salarié et la période spécifiée sans problème de multiplication des valeurs SOMME.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal