MySQL LEFT JOIN SELECT ne sélectionne pas tous les enregistrements de gauche?

StackOverflow https://stackoverflow.com/questions/205340

  •  03-07-2019
  •  | 
  •  

Question

Les résultats d'une requête MySQL SELECT impliquant LEFT JOIN me donnent des résultats étranges. Je ne comprends pas si ma compréhension de LEFT JOIN est faux ou si je vois un comportement vraiment étrange.

J'ai deux tables avec une relation plusieurs-à-un: pour chaque enregistrement dans table 1 , il existe 0 ou plusieurs enregistrements dans table 2 . Je souhaite sélectionner tous les enregistrements du tableau 1 avec une colonne qui compte le nombre d'enregistrements liés du tableau 2. Si je comprends bien, JOINDRE GAUCHE doit toujours renvoyer tous les enregistrements du LEFT côté de l'instruction.

Voici une base de données de test présentant le problème:

CREATE DATABASE Test;
USE Test;

CREATE TABLE Dates (
   dateID INT UNSIGNED NOT NULL AUTO_INCREMENT,
   date DATE NOT NULL,
   UNIQUE KEY (dateID)
) TYPE=MyISAM;


CREATE TABLE Slots (
   slotID INT UNSIGNED NOT NULL AUTO_INCREMENT,
   dateID INT UNSIGNED NOT NULL,
   UNIQUE KEY (slotID)
) TYPE=MyISAM;

INSERT INTO Dates (date) VALUES ('2008-10-12'),('2008-10-13'),('2008-10-14');
INSERT INTO Slots (dateID) VALUES (3);

La table Dates contient trois enregistrements et l'emplacement 1 - et cet enregistrement pointe sur le troisième enregistrement dans Dates.

Si je fais la requête suivante ..

SELECT d.date, count(s.slotID) FROM Dates AS d LEFT JOIN Slots AS s ON s.dateID=d.dateID GROUP BY s.dateID;

.. Je m'attends à voir une table avec 3 lignes - deux avec un nombre de 0 et une avec un nombre de 1. Mais ce que je vois réellement est la suivante:

+------------+-----------------+
| date       | count(s.slotID) |
+------------+-----------------+
| 2008-10-12 |               0 |
| 2008-10-14 |               1 |
+------------+-----------------+

Le premier enregistrement avec un compte zéro apparaît, mais le dernier enregistrement avec un compte zéro est ignoré.

Est-ce que je fais quelque chose de mal ou est-ce que je ne comprends pas ce que LEFT JOIN est censé faire?

Était-ce utile?

La solution

Vous devez GROUP BY d.dateID . Dans deux de vos cas, s.DateID est NULL ( LEFT JOIN ) et ceux-ci sont combinés ensemble.

Je pense que vous constaterez également qu'il s'agit d'un SQL non valide (ANSI) SQL, car d.date ne fait pas partie d'un GROUP BY ou du résultat d'une opération d'agrégat, et ne devrait pas pouvoir être SELECT édité

Autres conseils

Je pense que vous voulez dire grouper par d.dateId.

Essayez de supprimer GROUP BY s.dateID

Les dates pour 10-12 et 10-13 sont regroupées par vous. S'agissant de 2 valeurs nulles, le nombre est évalué à 0

Je ne sais pas si cela est valide dans MySQL mais vous pourriez probablement annuler cette erreur à l'avenir en utilisant la syntaxe suivante

SELECT date, count(slotID) as slotCount
FROM Dates LEFT OUTER JOIN Slots USING (dateID)
GROUP BY (date)

En utilisant la clause USING, vous ne recevez pas deux ID de date à suivre.

remplacez GROUP BY s.dateID par d.dateID.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top