sql >> Databáze >  >> RDS >> Mysql

LEFT JOIN nevrátí všechny záznamy z levé postranní tabulky

Problém může být v tom, že filtrujete na spojené tabulce pomocí podmínky where, která bude filtrovat i služby oddělení, které nemají shodu ve spojení, přesunete filtrování ve spojení a ponecháte pouze filtry na d v 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

Abych vysvětlil, proč k tomu dochází, provedu vás tím, co se stane s vaším dotazem a s mým dotazem, jako datovou sadu použiji toto:

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

cities

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

Nejprve si projdu váš dotaz.

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

Takže nepůjdeme krok za krokem, vyberete tři státy, vlevo se spojíte s městy končícími:

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

Populaci filtrujete pomocí WHERE c.population < 10 , v tuto chvíli vlevo s tímto:

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

Ztratili jste Německo, protože Berlín měl 10 obyvatel, ale ztratili jste i Švédsko který měl NULL, pokud jste chtěli zachovat hodnoty null, měli byste to zadat v dotazu:

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

Což vrátí:

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

Nyní můj dotaz:

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

Než je spojíme, vyfiltrujeme města tabulky (pomocí AND c.population < 10 podmínku za ON ), co zbývá:

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

Protože Milán je jediné město s méně než 10 obyvateli, teď můžeme spojit dva stoly:

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

Jak můžete vidět, data z levé tabulky zůstávají, protože byla použita pouze podmínka filtrování do tabulky měst.

Sada výsledků se mění v závislosti na tom, čeho chcete dosáhnout, pokud například chcete filtrovat Německo, protože Berlín má méně než 10 obyvatel a zachovat Švédsko, měli byste použít první přístup přidáním IS NULL Pokud ji chcete zachovat, měli byste použít druhý přístup a předfiltrovat tabulku napravo od levého spojení.




  1. Nahrazení určitého znaku v e-mailových adresách znakem „*“ v dotazu SQL

  2. Jak zlepšit rychlost zápisu InnoDB za sekundu v MySQL DB

  3. Zdá se, že PHP foreach user script způsobí, že Apache zamrzne

  4. Kolik místa na disku je potřeba k uložení hodnoty NULL pomocí postgresql DB?