sql >> Database >  >> RDS >> Mysql

LEFT JOIN retourneert niet alle records uit de linkerzijtabel

Het probleem kan zijn dat u op de samengevoegde tabel filtert met behulp van de waar-voorwaarde die ook de afdelingsservices filtert die geen overeenkomst hebben in de join, de filtering in de join verplaatst en alleen de filters op d in de waar-clausule:

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

Om uit te leggen waarom dit gebeurt, zal ik u uitleggen wat er gebeurt met uw zoekopdracht en met mijn zoekopdracht, als dataset gebruik ik dit:

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

cities

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

Ik zal eerst je vraag doornemen.

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

Dus laten we niet stap voor stap gaan, je selecteert de drie staten, links voeg je bij steden eindigend met:

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

U filtert de populatie met WHERE c.population < 10 , op dit punt links met dit:

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

Je verliest Duitsland omdat de bevolking van Berlijn 10 was maar je verloor ook Zweden die NULL had, als u de nulls wilde behouden, had u dit in de query moeten specificeren:

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

Wat terugkomt:

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

Nu mijn vraag:

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

Voordat we de twee samenvoegen, filteren we de tabelsteden (met behulp van de AND c.population < 10 voorwaarde na de ON ), wat overblijft is:

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

Omdat Milaan de enige stad is met een bevolking van minder dan 10, nu we kunnen de twee tafels samenvoegen:

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

Zoals u kunt zien, blijven de gegevens uit de linkertabel behouden omdat de filtervoorwaarde alleen . is toegepast naar de tabel met steden.

De resultatenset verandert afhankelijk van wat u wilt bereiken, als u bijvoorbeeld Duitsland wilt filteren omdat Berlijn een bevolking heeft van minder dan 10 en Zweden wilt behouden, moet u de eerste benadering gebruiken door de IS NULL toe te voegen voorwaarde, als u deze in plaats daarvan wilt behouden, moet u de tweede benadering gebruiken en de tabel aan de rechterkant van de linker join vooraf filteren.




  1. Zijn er ontsnappende syntaxis voor de psql-variabele in PostgreSQL-functies?

  2. Wat is een opgeslagen procedure?

  3. Hoe verkrijg ik servicereferenties voor een service-instance die is gemaakt op IBM Bluemix zonder de instance te binden aan een toepassing op Bluemix?

  4. Cachegegevens in PHP SESSION, of elke keer opvragen vanuit db?