Mysql
 sql >> Datenbank >  >> RDS >> Mysql

LEFT JOIN gibt nicht alle Datensätze aus der Tabelle der linken Seite zurück

Das Problem könnte sein, dass Sie die verbundene Tabelle mit der where-Bedingung filtern, die auch die Abteilungsdienste filtert, die keine Übereinstimmung im Join haben, die Filterung im Join verschieben und nur die Filter auf d in der where-Klausel:

SELECT d.mt_code,
   d.dep_name,
   d.service_name,
   COUNT(t.id)
FROM DepartmentService AS d
LEFT JOIN tbl_outgoing AS t 
  ON d.mt_code = t.depCode 
    AND t.smsc = "mobitelMT"
    AND t.sendDate BETWEEN '2014-07-01' AND '2014-07-02'
WHERE d.service_type = 'MT'
GROUP BY d.mt_code

Um zu erklären, warum dies passiert, werde ich Sie durch das führen, was mit Ihrer Abfrage und meiner Abfrage passiert, als Datensatz verwende ich Folgendes:

states
 ____ _________ 
| id | state   |
|  1 | Germany |
|  2 | Italy   |
|  3 | Sweden  |
|____|_________|

cities

 ____ ________ ___________ ____________
| id | city   | state_fk  | population |
|  1 | Berlin |        1  |         10 |
|  2 | Milan  |        2  |          5 |
|____|________|___________|____________|

Zuerst gehe ich Ihre Anfrage durch.

SELECT s.id, s.state, c.population, c.city
FROM states s
LEFT JOIN cities c
ON c.state_fk = s.id
WHERE c.population < 10

Gehen Sie also nicht Schritt für Schritt vor, sondern wählen Sie die drei Bundesstaaten aus, verbinden Sie sich links mit den Städten und enden Sie mit:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  1 | Germany |         10 | Berlin |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

Dann filtern Sie die Population mit WHERE c.population < 10 , an dieser Stelle links mit diesem:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  2 | Italy   |          5 | Milan  |
|____|_________|____________|________|

Sie verlieren Deutschland, weil Berlin 10 Einwohner hat aber Sie haben auch Schweden verloren die NULL hatte, wenn Sie die Nullen behalten wollten, hätten Sie sie in der Abfrage angeben sollen:

WHERE (c.population < 10 OR IS NULL c.population)

Was zurückgibt:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

Nun meine Abfrage:

SELECT s.id, s.state, c.population, c.city
FROM states s
LEFT JOIN cities c
ON c.state_fk = s.id
  AND c.population < 10

Bevor wir die beiden zusammenführen, filtern wir die Tabellenstädte (mit AND c.population < 10). Zustand nach dem ON ), was bleibt ist:

 ____ ________ ___________ ____________
| id | city   | state_fk  | population |
|  2 | Milan  |        2  |          5 |
|____|________|___________|____________|

Denn Mailand ist jetzt die einzige Stadt mit weniger als 10 Einwohnern Wir können die beiden Tabellen verbinden:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  1 | Germany |       NULL | NULL   |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

Wie Sie sehen können, bleiben die Daten aus der linken Tabelle erhalten, da die Filterbedingung nur angewendet wurde zur Städtetabelle.

Die Ergebnismenge ändert sich je nachdem, was Sie erreichen möchten. Wenn Sie beispielsweise Deutschland filtern möchten, weil Berlin weniger als 10 Einwohner hat, und Schweden behalten möchten, sollten Sie den ersten Ansatz verwenden und den IS NULL hinzufügen Bedingung, wenn Sie sie stattdessen behalten möchten, sollten Sie den zweiten Ansatz verwenden und die Tabelle rechts vom linken Join vorfiltern.