sql >> Database teknologi >  >> RDS >> Mysql

LEFT JOIN returnerer ikke alle poster fra venstre sidetabel

Problemet kan være, at du filtrerer på den joinforbundne tabel ved at bruge where-betingelsen, som også vil filtrere de afdelingstjenester, der ikke har et match i joinforbindelsen, flytte filtreringen i joinforbindelsen og kun lade filtrene være på d i where-klausulen:

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
 

For at forklare, hvorfor dette sker, vil jeg lede dig gennem, hvad der sker med din forespørgsel og med min forespørgsel, som datasæt vil jeg bruge dette:

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

cities

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

Først vil jeg gennemgå din forespørgsel.

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
 

Så lad os gå trin for trin, du vælger de tre stater, og tilmeld dig med byer, der ender med:

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

Du filtrerer populationen ved hjælp af WHERE c.population < 10 , på dette tidspunkt venstre med dette:

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

Du mister Tyskland, fordi Berlins befolkning var 10 men du mistede også Sverige som havde NULL, hvis du ville beholde nullerne, skulle du have angivet det i forespørgslen:

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

Hvilket returnerer:

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

Nu min forespørgsel:

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
 

Før vi forbinder de to, filtrerer vi tabelbyerne (ved hjælp af AND c.population < 10 tilstand efter ON ), hvad der er tilbage er:

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

Fordi Milano er den eneste by med mindre end 10 indbyggere nu vi kan samle de to borde:

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

Som du kan se, forbliver dataene fra den venstre tabel, fordi filtreringsbetingelsen kun blev anvendt til bybordet.

Resultatsættet ændrer sig afhængigt af, hvad du ønsker at opnå, hvis du f.eks. vil filtrere Tyskland, fordi Berlin har en befolkning på mindre end 10 og beholde Sverige, skal du bruge den første tilgang ved at tilføje IS NULL betingelse, hvis du vil beholde den i stedet, skal du bruge den anden tilgang og forfiltrere tabellen til højre for venstre join.




  1. Hvordan håndterer man delvise datoer (2010-00-00) fra MySQL i Django?

  2. Oracle Trigger-oprettelse med kompileringsfejl, ORA-02289:sekvens eksisterer ikke

  3. Hvordan indsætter man 'NULL'-værdier i PostgreSQL-databasen ved hjælp af Python?

  4. Bruger online offline status - offline status problem