Pregunta 1¿Cuál es la forma correcta de unir las tres tablas sales, employee y department?
Uniones de tablas (3) — Apilar WHERE / ORDER BY / CASE sobre un JOIN
Apila un INNER JOIN de 3 tablas sobre sales, employee y department, luego añade filtros WHERE, claves secundarias ORDER BY, una etiqueta de franja CASE con High/Mid/Low y una clasificación con SUM — todo en vivo en tu navegador.
Los datos que usaremos — department, employee y sales
En los artículos anteriores viste las distintas variantes de unión — INNER JOIN, OUTER JOIN y auto-unión.
En este artículo vas a apilar filtros WHERE, ORDER BY y etiquetas de franja con CASE sobre un JOIN y construir la forma de un informe de agregación que vas a encontrar de verdad en el trabajo.
Los datos son department (6 departamentos) y employee (30 personas), más una nueva tabla sales (50 filas) con las líneas de venta.
sales.emp_id es una clave foránea que apunta a employee.emp_id.
Uniremos las tres tablas para construir un informe que imprime el departamento y el nombre del representante junto a cada venta.
Unir tres tablas — encadenar JOINs
Para unir tres o más tablas solo tienes que encadenar cláusulas `JOIN ... ON ...` una tras otra.
Escribe FROM sales s JOIN employee e ON s.emp_id = e.emp_id JOIN department d ON e.dept_id = d.dept_id — primero enlaza sales con employee por emp_id, luego enlaza ese resultado con department por dept_id.
La forma más natural de leer el orden es: «parte de las líneas de venta (sales) y luego añade la información del empleado y del departamento sobre ellas».
Todo es INNER JOIN, así que solo sobreviven las filas que coinciden en las tres tablas.
En este conjunto de datos los 12 empleados con ventas pertenecen a algún departamento, así que el INNER JOIN de 3 tablas devuelve las 50 filas de sales.
-- Añade el nombre del representante y dept_name a cada venta (INNER JOIN de 3 tablas)
SELECT s.sale_id, e.name, d.dept_name, s.amount, s.sale_date
FROM sales s
JOIN employee e
ON s.emp_id = e.emp_id
JOIN department d
ON e.dept_id = d.dept_id
ORDER BY s.sale_id;
Filtrar con WHERE, ordenar con ORDER BY
Una vez que el JOIN está en su sitio, usa WHERE para conservar solo las filas que necesitas y ORDER BY para disponerlas de forma legible.
Las condiciones de WHERE pueden referirse a columnas de cualquier tabla unida.
WHERE d.location = 'Tokyo' conserva solo las ventas de departamentos en Tokyo, y WHERE s.amount >= 400000 conserva solo las ventas de alto valor.
Las cláusulas SQL se escriben en el orden FROM → JOIN → ON → WHERE → ORDER BY.
WHERE filtra las filas después de que el JOIN se completa, y ORDER BY ordena al final.
Para ordenar por varias columnas, sepáralas con coma: ORDER BY col1 DESC, col2. Las filas con empate en col1 se ordenan luego por col2 (una clave secundaria para estabilizar el orden).
-- Solo las ventas de departamentos con sede en Osaka, mayor importe primero
SELECT e.name, d.dept_name, s.amount, s.sale_date
FROM sales s
JOIN employee e
ON s.emp_id = e.emp_id
JOIN department d
ON e.dept_id = d.dept_id
WHERE d.location = 'Osaka'
ORDER BY s.amount DESC, s.sale_id;
Añade etiquetas de franja con CASE — termina con un informe clasificado
Sobre JOIN, WHERE y ORDER BY, una expresión CASE puede añadir una columna con etiquetas de franja para el importe, convirtiendo el resultado en un informe que una persona puede leer de un vistazo.
CASE evalúa condiciones de arriba abajo y devuelve el valor de la primera rama que resulte verdadera. Puedes ponerlo directamente dentro de la lista de columnas del SELECT (forma con búsqueda: CASE WHEN condición THEN valor ... ELSE valor_por_defecto END).
Por ejemplo, divide cada venta en tres franjas por amount: High cuando amount >= 400000, Mid cuando amount >= 200000 y Low en otro caso — exponiendo la franja en una columna con alias band.
Mantén las etiquetas como cadenas ASCII fijas ('High' / 'Mid' / 'Low') para que el resultado siga siendo portable entre entornos.
Con JOIN de 3 tablas, WHERE, ORDER BY y CASE combinados en una sola consulta, acabas teniendo casi exactamente la forma de los informes de agregación que se construyen cada día en equipos reales.
-- Ejemplo: divide amount en 2 franjas (Large >= 300000)
SELECT e.name, d.dept_name, s.amount,
CASE
WHEN s.amount >= 300000 THEN 'Large'
ELSE 'Small'
END AS size
FROM sales s
JOIN employee e
ON s.emp_id = e.emp_id
JOIN department d
ON e.dept_id = d.dept_id
WHERE d.dept_name = 'Sales'
ORDER BY s.sale_id;
Los empleados sin ventas desaparecen con INNER JOIN
Todos los informes de este artículo usan INNER JOIN, así que los 18 empleados sin ninguna venta nunca aparecen en el resultado.
Si necesitas un informe que incluya a todos los empleados — con ceros para los que no tuvieron ventas — empieza con employee como columna vertebral y haz LEFT JOIN de sales sobre ella, luego envuelve el SUM en COALESCE(SUM(s.amount), 0) para convertir los totales NULL en 0.
Siempre que los números de un informe no cuadren, lo primero que hay que sospechar es que «el tipo de unión equivocado está descartando en silencio filas que deberían estar ahí».
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2Para SELECT ... FROM sales s JOIN ... WHERE d.location = 'Tokyo' ORDER BY s.amount DESC, ¿en qué orden se evalúan las cláusulas?
Pregunta 3Dado CASE WHEN s.amount >= 400000 THEN 'High' WHEN s.amount >= 200000 THEN 'Mid' ELSE 'Low' END AS band, ¿cuál es band para una fila con amount = 450000?