Ir al contenido
wannacode

El orden de ejecución de una consulta

En resumen: Una consulta SQL se escribe empezando por SELECT, pero la base la ejecuta en el orden FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT.

Problema

Aquí funciona, allí no

En la lección de los grupos, ORDER BY month usó el alias de SELECT. En la lección de HAVING repetimos todo el SUM(...), y SUM en WHERE dio un error. ¿Por qué un alias funciona en un sitio y en otro no?

La respuesta está en el orden en que la base lee la consulta. No es el orden en que tú la escribes.

La idea

Se escribe en un orden, se ejecuta en otro

Tú escribes así:

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

La base piensa así:

  1. FROM: de dónde vienen las filas;
  2. WHERE: qué filas se quedan;
  3. GROUP BY: los grupos;
  4. HAVING: qué grupos se quedan;
  5. SELECT: qué se muestra y cómo se llama;
  6. ORDER BY: el orden;
  7. LIMIT: cuántas filas.

Este es el orden lógico de ejecución de una consulta. Los tres meses con más movimiento, sin los pedidos cancelados:

SQLbase de datos: tienda

Paso a paso: FROM toma los 60 pedidos. WHERE quita los 7 cancelados y quedan 53. GROUP BY los divide en 14 meses. HAVING conserva los seis con al menos 5 pedidos. SELECT calcula el mes y la cuenta y les pone nombre. ORDER BY los ordena, y LIMIT toma los tres primeros.

Más precisamente, para curiosos

Este es el orden en que la consulta debe parecer que se ejecuta. El plan real puede ser distinto: la base puede usar un índice o saltarse un paso, siempre que el resultado sea el mismo. Los planes de consulta los veremos en el módulo de índices.

La idea

Por qué el alias funciona en ORDER BY

El alias nace en SELECT, en el paso 5. ORDER BY es el paso 6, así que el nombre ya existe:

SQLbase de datos: tienda

Los tres pedidos más grandes. Esto funciona en todas las bases. En WHERE, GROUP BY y HAVING, según la regla, el alias todavía no existe, porque van antes que SELECT.

Pruébalo

Los clientes más activos

Muestra los cinco clientes con más pedidos: customer_id y la cantidad en una columna llamada orders, el que más primero. En caso de empate va primero el customer_id menor.

SQLbase de datos: tienda

Míralo

Lo que SQLite perdona

Según la regla, un alias en WHERE no debería funcionar. Los productos que con un 20 % de descuento cuestan menos de 1 €:

SQLbase de datos: tienda

SQLite lo acepta. También acepta un alias en GROUP BY:

SQLbase de datos: tienda

Otras bases no son tan permisivas. PostgreSQL acepta un alias en GROUP BY, pero no en WHERE: allí dice que la columna sale no existe. SQL Server no lo acepta ni en WHERE ni en GROUP BY.

La permisividad de SQLite tiene límites. Si el alias se llama igual que una columna, WHERE toma la columna:

SQLbase de datos: tienda

Salen dos productos, no cuatro: WHERE price < 1 mira el precio real, no el rebajado. Y un alias de una agregación en WHERE sigue siendo «misuse of aggregate», porque en el paso 2 todavía no hay grupos:

SQLbase de datos: tienda

Una consulta que funciona en todas partes: en WHERE repite la expresión (WHERE price * 0.8 < 1), y usa los alias con libertad en ORDER BY.

Ejercicio

El informe mensual

La dueña quiere un informe de 2026: para cada mes, cuántos pedidos hay (sin los cancelados) y de cuántos clientes distintos. Los meses con menos de 3 pedidos son demasiado tranquilos y no los necesita.

Muestra las columnas month (año-mes), orders y customers de los meses de 2026 con al menos 3 pedidos, sin contar los cancelados, en el orden de los meses.

SQLbase de datos: tienda

Test

Ponte a prueba

1. ¿Por qué parte empieza la base cuando ejecuta la consulta?
2. ¿Por qué funciona ORDER BY total cuando total es un alias de SELECT?
3. ¿Qué es cierto de WHERE sale < 1, cuando sale es un alias de SELECT?
4. La consulta tiene ORDER BY orders DESC y LIMIT 3. ¿Cuándo se toman las tres filas?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·