INNER JOIN y LEFT JOIN
BásicoINNER JOIN devuelve solo las filas que tienen pareja en las dos tablas. LEFT JOIN conserva todas las filas de la tabla izquierda y completa con NULL las columnas de la derecha cuando no hay pareja.
Sintaxis
SELECT ...
FROM tabla_izquierda AS a
LEFT JOIN tabla_derecha AS b ON b.clave = a.clave;Ejemplo
SELECT
c.id,
c.full_name,
count(o.id) AS pedidos
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id
WHERE c.country = 'UY'
AND c.city = 'Salto'
GROUP BY c.id, c.full_name
ORDER BY pedidos, c.id
LIMIT 6;Resultado
| id | full_name | pedidos |
|---|---|---|
| 729 | Paula Castro | 0 |
| 780 | Mateo González | 0 |
| 2888 | Constanza Aguilar | 0 |
| 118 | Regina Navarro | 1 |
| 1159 | Rodrigo Díaz | 2 |
| 1397 | Nicolás Romero | 2 |
Cómo leerlo
Los tres clientes de Salto sin pedidos aparecen con 0 gracias al LEFT JOIN. Con INNER JOIN desaparecerían del resultado. Se cuenta count(o.id) y no count(*): count(*) contaría la fila completada con NULL y mostraría 1 para quien nunca compró.
Error común
Así no
SELECT c.id, count(o.id) AS pedidos
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id
WHERE c.city = 'Salto'
AND o.status = 'delivered'
GROUP BY c.id;Filtrar la tabla derecha en el WHERE. En las filas sin pareja o.status es NULL, la condición no se cumple y esas filas se descartan: el LEFT JOIN pasa a comportarse como un INNER JOIN. La condición sobre la tabla derecha va en el ON: ON o.customer_id = c.id AND o.status = 'delivered'.
En otros motores: PostgreSQL, SQL Server, Oracle, Snowflake, BigQuery
PostgreSQLSQL ServerOracleSnowflakeBigQuery
FULL OUTER JOINconserva las filas sin pareja de los dos lados. MySQL no lo tiene: se arma con unLEFT JOINunido porUNIONa unRIGHT JOIN.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.