sql >> Base de Datos >  >> RDS >> Mysql

LEFT JOIN no devuelve todos los registros de la tabla del lado izquierdo

El problema podría ser que esté filtrando en la tabla unida usando la condición where que filtrará también los servicios del departamento que no tienen una coincidencia en la unión, mueva el filtrado en la unión y deje solo los filtros en d en la cláusula 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

Para explicar por qué sucede esto, lo guiaré a través de lo que sucede con su consulta y con mi consulta, como conjunto de datos usaré esto:

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

cities

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

Primero revisaré su consulta.

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

Entonces, vayamos paso a paso, seleccione los tres estados, únase a la izquierda con las ciudades y termine con:

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

La población se filtra usando WHERE c.population < 10 , en este punto tu izquierda con esto:

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

Perdiste Alemania porque la población de Berlín era de 10 pero también perdiste Suecia que tenía NULL, si quería mantener los valores nulos, debería haberlo especificado en la consulta:

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

Que devuelve:

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

Ahora mi consulta:

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

Antes de unir las dos, filtramos las ciudades de la tabla (usando AND c.population < 10 condición después de ON ), lo que queda es:

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

Porque Milán es la única ciudad con menos de 10 habitantes, ahora podemos unir las dos tablas:

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

Como puede ver, los datos de la tabla de la izquierda se mantienen porque la condición de filtrado se aplicó solo a la tabla de ciudades.

El conjunto de resultados cambia según lo que desee lograr, si, por ejemplo, desea filtrar Alemania porque Berlín tiene una población menor de 10 y mantener Suecia, debe usar el primer enfoque agregando IS NULL condición, si desea mantenerlo en su lugar, debe usar el segundo enfoque y filtrar previamente la tabla a la derecha de la combinación izquierda.