Mysql
 sql >> Baza danych >  >> RDS >> Mysql

LEFT JOIN nie zwraca wszystkich rekordów z lewej strony tabeli

Problem może polegać na tym, że filtrujesz na połączonej tabeli przy użyciu warunku where, który odfiltruje również usługi departamentów, które nie mają dopasowania w złączeniu, przenieś filtrowanie w złączeniu i pozostaw tylko filtry na d w klauzuli WHERE:

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

Aby wyjaśnić, dlaczego tak się dzieje, przeprowadzę Cię przez to, co dzieje się z Twoim zapytaniem i moim zapytaniem, jako zestaw danych użyję tego:

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

cities

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

Najpierw omówię Twoje zapytanie.

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

Więc nie idźmy krok po kroku, wybierasz trzy stany, lewy łączy się z miastami kończąc na:

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

Filtrujesz populację za pomocą WHERE c.population < 10 , w tym miejscu po lewej stronie z tym:

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

Tracisz Niemcy, bo populacja Berlina liczyła 10 osób ale straciłeś też Szwecję który miał NULL, jeśli chcesz zachować wartości null, powinieneś podać je w zapytaniu:

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

Który powraca:

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

Teraz moje zapytanie:

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

Przed dołączeniem do tych dwóch filtrujemy miasta w tabeli (za pomocą AND c.population < 10 warunek po ON ), pozostaje tylko:

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

Ponieważ Mediolan jest jedynym miastem o populacji poniżej 10 osób, teraz możemy dołączyć do dwóch stołów:

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

Jak widać dane z lewej tabeli pozostają, ponieważ warunek filtrowania został zastosowany tylko do tabeli miast.

Zestaw wyników zmienia się w zależności od tego, co chcesz osiągnąć, jeśli na przykład chcesz filtrować Niemcy, ponieważ Berlin ma populację mniejszą niż 10 i zachować Szwecję, powinieneś użyć pierwszego podejścia dodając IS NULL warunek, jeśli chcesz go zachować, powinieneś użyć drugiego podejścia i wstępnie przefiltrować tabelę po prawej stronie lewego połączenia.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak znaleźć kolejny rekord po określonym w SQL?

  2. Pobierz zmienną w pętli while na podstawie tego, co wybiera użytkownik?

  3. Oblicz mediany dla wielu kolumn w tej samej tabeli w jednym wywołaniu zapytania

  4. Jak naprawić błąd „Wartość poza zakresem dostosowana do kolumny”?

  5. Czy użycie magic_quotes() wpływa na użycie mysql_real_escape_string()