sql >> Databasteknik >  >> RDS >> Mysql

LEFT JOIN returnerar inte alla poster från den vänstra sidotabellen

Problemet kan vara att du filtrerar på den joinade tabellen med hjälp av where-villkoret som kommer att filtrera även de avdelningstjänster som inte har en matchning i joinen, flytta filtreringen i joinen och lämna bara filtren på d i where-satsen:

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

För att förklara varför detta händer kommer jag att gå igenom vad som händer med din fråga och med min fråga, som datauppsättning använder jag detta:

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 ska jag gå igenom din fråga.

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å låt oss gå steg för steg, du väljer de tre staterna, vänster gå med med städer som slutar med:

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

Du filtrerar populationen med WHERE c.population < 10 , vid det här laget lämnade du det här:

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

Du förlorar Tyskland eftersom Berlins befolkning var 10 men du förlorade också Sverige som hade NULL, om du ville behålla nollvärdena borde du ha angett det i frågan:

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

Som returnerar:

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

Nu min fråga:

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

Innan vi förenar de två filtrerar vi tabellstäderna (med AND c.population < 10 skick efter ON ), det som återstår är:

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

Eftersom Milano är den enda staden med mindre än 10 invånare nu vi kan slå samman de två borden:

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

Som du kan se finns data från den vänstra tabellen kvar eftersom filtreringsvillkoret endast tillämpades till stadsbordet.

Resultatuppsättningen ändras beroende på vad du vill uppnå, om du till exempel vill filtrera Tyskland eftersom Berlin har mindre än 10 invånare och behålla Sverige bör du använda den första metoden och lägga till IS NULL villkor, om du vill behålla det istället, bör du använda den andra metoden och förfiltrera tabellen till höger om vänster join.




  1. JSON_TABLE() Funktion i Oracle

  2. Hur skickar man en array till where-villkoret i CodeIgniter?

  3. Importera data från Excel-kalkylblad eller CVS till MySQL

  4. ILIKE Matcha ordgränser PostgreSQL 9