🎧 Escuchar esta guía
El punto de partida: dos tablas, un enlace
-- users -- orders
-- id | name -- id | user_id | amount
-- 1 | Ada -- 1 | 1 | 19.99
-- 2 | Lin -- 2 | 1 | 5.00
-- 3 | Sam -- 3 | 2 | 42.50
-- (Sam no tiene pedidos: fíjate en lo que le ocurre)
INNER JOIN: solo las coincidencias
SELECT users.name, orders.amount
FROM orders
JOIN users ON orders.user_id = users.id;
-- Ada | 19.99
-- Ada | 5.00 ← Ada coincide dos veces → aparece dos veces
-- Lin | 42.50
-- (Sam no aparece. Sin coincidencia no hay fila. Eso es INNER.)
LEFT JOIN: conserva todas las filas de la izquierda
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON orders.user_id = users.id;
-- Ada | 19.99
-- Ada | 5.00
-- Lin | 42.50
-- Sam | NULL ← se conserva; el lado derecho se rellena con NULL
¿Qué tabla es la «izquierda»? La que aparece después de FROM. «Todos los usuarios y sus pedidos» → users a la izquierda. «Todos los pedidos y su usuario» → orders a la izquierda. Di la frase en voz alta: la frase elige la tabla.
El uso clásico: encontrar filas sin coincidencia
-- "usuarios que nunca han hecho un pedido"
SELECT users.name
FROM users
LEFT JOIN orders ON orders.user_id = users.id
WHERE orders.id IS NULL; -- la ausencia de coincidencia ES el filtro
-- → Sam
El error que se come una tarde entera
Añade una condición normal sobre la tabla de la derecha al WHERE de un LEFT JOIN —
Añade una condición normal sobre la tabla de la derecha al WHERE de un LEFT JOIN —
WHERE orders.amount > 10— y las filas con NULL desaparecen: NULL > 10 no es verdadero, así que Sam queda fuera y el LEFT JOIN se comporta como INNER sin avisar. Solución: coloca las condiciones de la tabla derecha en la cláusula ON —ON orders.user_id = users.id AND orders.amount > 10— para filtrar las coincidencias sin perder las filas que no tienen pareja.
Tres tablas: es lo mismo, dos veces
SELECT u.name, o.amount, p.title
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;
-- cada JOIN añade otra tabla a una fila que se va ensanchando.
-- los alias cortos (o, u, p) mantienen la consulta legible.
El resto de la familia, sin rodeos
RIGHT JOIN -- es un LEFT JOIN con las tablas intercambiadas. casi nadie
-- lo escribe; pásalo a LEFT y conserva un único modelo mental.
FULL JOIN -- conserva las filas sin pareja de AMBOS lados. raro; auditorías.
CROSS JOIN -- todas las combinaciones (sin ON). tallas × colores = variantes.
📚 Esta es una página de nuestra serie de SQL. El curso intensivo completo incluye trampas de NULL, GROUP BY y la historia de terror de UPDATE: SQL en 10 minutos →