1. Faro

Nivel 5 · ¿Por qué falla esta consulta?

La solicitud

De Tyler Morgan, Ingeniero de Datos Junior

“Oye, mi consulta sigue dando error y no veo por qué. Intento obtener los canales con más de 3,000 pedidos. ¿Puedes echarle un vistazo?”

Tu objetivo

Elige la explicación de por qué falla la consulta de Tyler.

Tyler ejecuta SELECT channel, COUNT(*) AS orders FROM orders WHERE COUNT(*) > 3000 GROUP BY channel; y obtiene un error. ¿Por qué?

Elige una respuesta y luego compruébala.

La lección

SQL se escribe en un orden y se evalúa en otro. Conocer el orden de evaluación convierte mensajes de error confusos en soluciones evidentes.

Orden escrito vs orden lógico

Tú escribes:

SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT

La base de datos evalúa lógicamente:

FROM → WHERE → GROUP BY → aggregates → HAVING → SELECT → ORDER BY → LIMIT

Los motores reales reordenan el trabajo internamente para ganar velocidad, pero deben devolver el mismo resultado que si siguieran este orden lógico. Así que puedes razonar con él con seguridad.

La consulta de Tyler

SELECT channel, COUNT(*) AS orders
FROM orders
WHERE COUNT(*) > 3000
GROUP BY channel;

En el paso de WHERE la base de datos mira un pedido a la vez. Todavía no hay grupos, así que ¿“el conteo” de qué? Postgres responde con aggregate functions are not allowed in WHERE, y DuckDB, MySQL y BigQuery dan errores parecidos. La solución:

SELECT channel, COUNT(*) AS orders
FROM orders
GROUP BY channel
HAVING COUNT(*) > 3000;

Lo que explica el orden

pregunta respuesta según el orden
¿Puede WHERE usar un agregado? No, los agregados vienen después.
¿Puede HAVING usar un agregado? Sí, para entonces ya existen.
¿Puede WHERE usar un alias de SELECT? No en SQL estándar, SELECT viene después.
¿Puede ORDER BY usar un alias de SELECT? Sí, se ejecuta después de SELECT.
¿LIMIT se aplica antes o después de ordenar? Después.

Como se señaló antes, DuckDB, MySQL y BigQuery relajan la regla de los alias en algunas cláusulas. Postgres sigue el estándar de cerca, por eso las historias de “en mi laptop funciona, en producción falla” suelen involucrar un alias en WHERE o HAVING.

Dónde encajan las funciones de ventana

Las funciones de ventana (capítulo 8) se evalúan en el paso de SELECT, después de HAVING. Por eso tampoco puedes filtrar por ROW_NUMBER() en WHERE, y por eso “top N por grupo” necesita una subconsulta o una CTE. Algunos almacenes (Snowflake, BigQuery, DuckDB) añaden una cláusula QUALIFY justo para esto.

Nota de entrevista

Poder recitar el orden lógico y usarlo para explicar un error es una señal fuerte. Cuando una consulta da error en una entrevista en vivo, di en voz alta a qué paso pertenece la expresión que falla. A los entrevistadores les importa más ese razonamiento que la sintaxis memorizada.

Errores comunes

  • Filtrar por un agregado en WHERE. WHERE COUNT(*) > 3000 falla; las condiciones sobre conteos y sumas pertenecen a HAVING.
  • Usar un alias de SELECT en WHERE. SELECT quantity * unit_price AS line_total ... WHERE line_total > 100 falla en Postgres y SQL Server, porque SELECT se ejecuta después de WHERE. Repite la expresión: WHERE quantity * unit_price > 100.
  • Filtrar por una función de ventana en WHERE. WHERE ROW_NUMBER() OVER (...) <= 3 no está permitido. Calcula el número en una CTE y filtra en la consulta externa.
  • Usar LIMIT sin ORDER BY y esperar las primeras filas. LIMIT solo corta; sin un ORDER BY, devuelve las filas que la base de datos alcance primero.

En SQL Server

El orden lógico es el mismo, así que la consulta de Tyler también falla allí. TOP se aplica en el mismo punto que LIMIT, después de ORDER BY, y un alias de SELECT puede usarse en ORDER BY pero no en WHERE, GROUP BY ni HAVING.

Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.