El orden lógico de una consulta
BásicoEscribes SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY … LIMIT, pero el motor lo evalúa como FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT (incluidas las funciones de ventana) → DISTINCT → ORDER BY → LIMIT. Cada cláusula solo ve lo que produjeron las anteriores.
Sintaxis
SELECT columnas, agregados, -- 5. calcular columnas y
funciones de ventana -- funciones de ventana
FROM tabla JOIN otra ON ... -- 1. armar las filas de partida
WHERE condición_por_fila -- 2. filtrar filas
GROUP BY columnas -- 3. formar grupos
HAVING condición_por_grupo -- 4. filtrar grupos
ORDER BY columnas -- 6. ordenar el resultado
LIMIT n; -- 7. cortarEjemplo
SELECT
c.country AS pais,
count(*) AS pedidos_entregados
FROM orders AS o
INNER JOIN customers AS c ON c.id = o.customer_id
WHERE o.status = 'delivered'
GROUP BY c.country
HAVING count(*) > 1000
ORDER BY pedidos_entregados DESC
LIMIT 3;Resultado
| pais | pedidos_entregados |
|---|---|
| MX | 4281 |
| AR | 3959 |
| CO | 1950 |
Cómo leerlo
El WHERE descarta los pedidos que no están en 'delivered' antes de agrupar; el HAVING descarta después los países con 1000 pedidos o menos. El alias pedidos_entregados funciona en ORDER BY porque esa cláusula se evalúa después del SELECT, y por eso el HAVING repite count(*).
Error común
Así no
SELECT c.country AS pais, count(*) AS pedidos_entregados
FROM orders AS o
INNER JOIN customers AS c ON c.id = o.customer_id
WHERE pedidos_entregados > 1000
GROUP BY c.country;Usar en el WHERE un alias o un agregado del SELECT. Cuando se evalúa el WHERE todavía no existen ni el alias ni los grupos, y PostgreSQL responde que la columna pedidos_entregados no existe. Una condición sobre un agregado va en el HAVING.
En otros motores: PostgreSQL, MySQL, BigQuery, Snowflake, SQL Server
PostgreSQL
PostgreSQL acepta el alias del
SELECTenORDER BYy enGROUP BY, pero no enWHEREni enHAVING.MySQLBigQuery
Aceptan el alias del
SELECTtambién enHAVING. Una consulta que lo aprovecha falla al llevarla a PostgreSQL o SQL Server.Snowflake
Permite reutilizar el alias incluso en
WHERE. Es cómodo, pero no es portable: si la consulta puede cambiar de motor, repite la expresión.SQL Server
Solo acepta el alias en
ORDER BY. EnGROUP BYhay que repetir la expresión completa.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.