SQL Interview Pro
Manual de SQL
Referencia rápida de las cláusulas, joins y funciones que más se repiten en entrevistas de data analyst. Los mismos términos que ves resaltados con hover en las soluciones, aquí explicados a fondo.
Cláusulas base
SELECT
Define qué columnas (o expresiones calculadas) va a devolver el resultado. Es lo primero que se escribe, pero lógicamente es de las últimas cosas que la base de datos resuelve — después de filtrar y agrupar las filas.
SELECT nombre, total FROM ventas;
FROM
Especifica la tabla (o tablas, si hay JOINs) de donde se van a leer las filas antes de aplicar cualquier filtro.
SELECT * FROM clientes;
WHERE
Filtra las filas individuales según una condición, ANTES de que se agrupen con GROUP BY. No puede usar funciones de agregación como COUNT() o SUM() directamente — para eso existe HAVING.
SELECT * FROM ventas WHERE monto > 1000;
GROUP BY
Junta las filas que comparten el mismo valor en una o más columnas, para que las funciones de agregación (COUNT, SUM, AVG...) calculen un resultado por grupo en vez de uno solo para toda la tabla.
SELECT pais, COUNT(*) FROM clientes GROUP BY pais;
HAVING
Igual que WHERE, pero se aplica DESPUÉS de GROUP BY — filtra grupos completos, no filas individuales. Por eso sí puede usar funciones de agregación en su condición.
SELECT pais, COUNT(*) c FROM clientes GROUP BY pais HAVING c > 10;
ORDER BY
Ordena las filas del resultado según una o más columnas. Va casi siempre al final del query, porque ordena lo que ya se filtró y agrupó. Usa ASC (ascendente, default) o DESC (descendente).
SELECT * FROM ventas ORDER BY monto DESC;
LIMIT
Limita cuántas filas devuelve el query, normalmente combinado con ORDER BY para quedarte con los "top N" según algún criterio.
SELECT * FROM ventas ORDER BY monto DESC LIMIT 5;
DISTINCT
Quita filas repetidas del resultado, comparando todas las columnas seleccionadas juntas. Útil para responder preguntas de "¿cuántos valores únicos hay?".
SELECT DISTINCT pais FROM clientes;
AS
Renombra una columna, expresión o tabla dentro del query, sin cambiar nada en la base de datos real. Muy usado para que los resultados de columnas calculadas tengan un nombre legible.
SELECT COUNT(*) AS total_clientes FROM clientes;
Joins
JOIN
Usado solo (sin INNER/LEFT/RIGHT antes) es equivalente a INNER JOIN — combina dos tablas y devuelve solo las filas que hacen match en ambas según la condición ON.
SELECT * FROM ventas v JOIN clientes c ON v.cliente_id = c.id;
INNER JOIN
Combina dos tablas y devuelve únicamente las filas donde la condición de unión (ON) se cumple en ambas. Si una fila no tiene match del otro lado, se descarta por completo.
SELECT * FROM ventas v INNER JOIN clientes c ON v.cliente_id = c.id;
LEFT JOIN
Devuelve todas las filas de la tabla de la izquierda, y si no hay match en la tabla de la derecha, rellena esas columnas con NULL. Muy usado para encontrar registros "sin actividad" (ej. clientes sin compras).
SELECT c.nombre, v.id FROM clientes c LEFT JOIN ventas v ON c.id = v.cliente_id;
RIGHT JOIN
Como LEFT JOIN pero al revés: conserva todas las filas de la tabla de la derecha, aunque no tengan match en la izquierda.
SELECT * FROM ventas v RIGHT JOIN clientes c ON v.cliente_id = c.id;
FULL JOIN
Combina LEFT y RIGHT JOIN: conserva todas las filas de ambas tablas, rellenando con NULL donde no haya match del otro lado.
SELECT * FROM a FULL JOIN b ON a.id = b.id;
ON
Especifica cómo se relacionan las dos tablas en un JOIN — normalmente comparando una llave foránea con una llave primaria.
... JOIN clientes c ON v.cliente_id = c.id
Funciones de agregación
COUNT
Cuenta cuántas filas hay. COUNT(*) cuenta todas las filas del grupo; COUNT(columna) cuenta solo las filas donde esa columna no es NULL.
SELECT COUNT(*) FROM ventas;
SUM
Suma todos los valores numéricos de una columna dentro de un grupo (o de toda la tabla, si no hay GROUP BY). Ignora los valores NULL.
SELECT SUM(monto) FROM ventas;
AVG
Calcula el promedio (media aritmética) de una columna numérica, ignorando los valores NULL en el cálculo.
SELECT AVG(monto) FROM ventas;
MIN
Devuelve el valor mínimo de una columna dentro del grupo — funciona con números, fechas y texto (orden alfabético).
SELECT MIN(fecha) FROM ventas;
MAX
Devuelve el valor máximo de una columna dentro del grupo — funciona con números, fechas y texto (orden alfabético).
SELECT MAX(monto) FROM ventas;
Funciones de ventana
ROW_NUMBER
Función de ventana que asigna un número secuencial único a cada fila dentro de su partición, según el ORDER BY del OVER(). Muy usada para quedarte con "el más reciente por grupo" o paginar resultados.
ROW_NUMBER() OVER (PARTITION BY cliente_id ORDER BY fecha DESC)
RANK
Como ROW_NUMBER, pero si dos filas empatan reciben el mismo número, y el siguiente rank salta (ej. 1, 2, 2, 4).
RANK() OVER (ORDER BY ventas_totales DESC)
DENSE_RANK
Como RANK, pero sin saltarse números después de un empate (ej. 1, 2, 2, 3 en vez de 1, 2, 2, 4).
DENSE_RANK() OVER (ORDER BY ventas_totales DESC)
PARTITION BY
Dentro de una función de ventana, divide las filas en particiones (grupos) — la función se reinicia para cada partición. Es el equivalente a GROUP BY pero sin colapsar las filas en una sola por grupo.
SUM(monto) OVER (PARTITION BY cliente_id)
OVER
Le dice a SQL que la función que la precede (COUNT, SUM, ROW_NUMBER...) debe calcularse "por ventana" en vez de colapsar todas las filas en una sola — cada fila conserva su lugar en el resultado.
COUNT(*) OVER (PARTITION BY categoria)
LAG
Función de ventana que accede al valor de una columna en una fila anterior dentro de la misma partición — muy usada para comparar un periodo contra el anterior.
LAG(monto) OVER (PARTITION BY cliente_id ORDER BY fecha)
LEAD
Como LAG, pero hacia adelante: accede al valor de una columna en una fila posterior dentro de la misma partición.
LEAD(monto) OVER (PARTITION BY cliente_id ORDER BY fecha)
Lógica condicional
CASE
Arranca una expresión condicional dentro de un SELECT — evalúa condiciones en orden con WHEN y devuelve un valor distinto según cuál se cumpla, como un if/else if/else.
CASE WHEN monto > 1000 THEN 'alto' ELSE 'bajo' END
WHEN
Cada WHEN dentro de un CASE evalúa una condición; la primera que se cumple es la que determina el resultado.
CASE WHEN pais = 'MX' THEN 'LATAM' ...
THEN
Define qué valor devolver cuando la condición del WHEN anterior es verdadera.
WHEN monto > 1000 THEN 'alto'
ELSE
Es opcional, pero si ninguna condición WHEN se cumple y no hay ELSE, el resultado es NULL.
CASE WHEN x > 0 THEN 'positivo' ELSE 'no positivo' END
END
Marca el final de la expresión CASE — sin él, SQL no sabe dónde termina la condición.
COALESCE
Recibe varios argumentos y devuelve el primero que no sea NULL — muy usado para poner un valor default cuando algo podría venir vacío.
COALESCE(telefono, 'sin teléfono')Subconsultas y conjuntos
UNION
Junta el resultado de dos SELECTs (con las mismas columnas) en uno solo, eliminando filas duplicadas automáticamente.
SELECT id FROM a UNION SELECT id FROM b;
UNION ALL
Igual que UNION, pero conserva los duplicados — más rápido porque no tiene que comparar filas para deduplicar.
SELECT id FROM a UNION ALL SELECT id FROM b;
IN
Comprueba si un valor está dentro de una lista fija o del resultado de una subconsulta.
WHERE pais IN ('MX', 'CO', 'AR')
EXISTS
Devuelve verdadero si la subconsulta que le sigue encuentra al menos una fila — no le importa cuántas ni cuáles, solo si hay alguna.
WHERE EXISTS (SELECT 1 FROM ventas WHERE ventas.cliente_id = c.id)
Otros
BETWEEN
Comprueba si un valor cae dentro de un rango, incluyendo ambos extremos.
WHERE fecha BETWEEN '2026-01-01' AND '2026-01-31'
LIKE
Busca coincidencias de texto usando comodines: % para cualquier cantidad de caracteres, _ para exactamente uno.
WHERE nombre LIKE 'Mar%'
IS NULL
Comprueba si un valor es NULL. No se puede usar '= NULL' en SQL — siempre hay que usar IS NULL o IS NOT NULL.
WHERE telefono IS NULL
AND
Combina dos condiciones — la fila solo pasa el filtro si ambas son verdaderas.
WHERE pais = 'MX' AND monto > 1000
OR
Combina dos condiciones — la fila pasa el filtro si al menos una es verdadera.
WHERE pais = 'MX' OR pais = 'CO'