El orden de ejecución en SQL
Aunque escribimos las consultas SQL en un orden determinado, el motor de base de datos las ejecuta en un orden diferente. Entender esto es clave para escribir consultas correctas y eficientes.
SELECT 5º FROM 1º WHERE 2º GROUP BY 3º HAVING 4º ORDER BY 6º LIMIT 7º FROM WHERE GROUP BY HAVING SELECT ORDER BY LIMIT Orden de escritura vs. orden de ejecución
| Paso | Lo que escribes | Cuándo se ejecuta |
|---|---|---|
| 1 | SELECT | 5º |
| 2 | FROM | 1º |
| 3 | WHERE | 2º |
| 4 | GROUP BY | 3º |
| 5 | HAVING | 4º |
| 6 | ORDER BY | 6º |
| 7 | LIMIT | 7º |
¿Por qué importa?
El orden de ejecución explica por qué:
- No puedes usar alias del SELECT en WHERE:
WHEREse ejecuta antes queSELECT. - Puedes usar alias del SELECT en ORDER BY:
ORDER BYse ejecuta después deSELECT. - HAVING filtra grupos, no filas:
HAVINGse ejecuta después deGROUP BY.
Flujo de ejecución
SELECT developer, COUNT(*) AS total -- 5. Selecciona columnas
FROM videogames -- 1. Accede a la tabla
WHERE year > 2000 -- 2. Filtra filas
GROUP BY developer -- 3. Agrupa
HAVING COUNT(*) > 1 -- 4. Filtra grupos
ORDER BY total DESC -- 6. Ordena resultado
LIMIT 5; -- 7. Limita filas devueltasLIMIT siempre se ejecuta al final, después de ordenar. Esto garantiza que obtienes los primeros N resultados ya ordenados.
Errores comunes por el orden de ejecución
Conocer el orden de ejecución te ayuda a evitar errores muy frecuentes:
1. No puedes usar un alias del SELECT en WHERE
-- ❌ Esto da error: 'total' no existe aún cuando se ejecuta WHERE
SELECT developer, COUNT(*) AS total
FROM videogames
WHERE total > 1
GROUP BY developer;
-- ✅ Usa la expresión completa o HAVING
SELECT developer, COUNT(*) AS total
FROM videogames
GROUP BY developer
HAVING COUNT(*) > 1;WHERE se ejecuta en el paso 2, pero el alias total se define en el paso 5 (SELECT). Por eso no puede encontrarlo.
2. No puedes usar funciones de agregación en WHERE
-- ❌ Esto da error: no se pueden usar agregaciones en WHERE
SELECT developer, COUNT(*) AS total
FROM videogames
WHERE COUNT(*) > 1
GROUP BY developer;
-- ✅ Usa HAVING para filtrar resultados de agregaciones
SELECT developer, COUNT(*) AS total
FROM videogames
GROUP BY developer
HAVING COUNT(*) > 1;Las funciones como COUNT(), SUM() o AVG() necesitan que los grupos ya estén formados. Como WHERE se ejecuta antes de GROUP BY, no tiene acceso a ellas.
3. SÍ puedes usar alias del SELECT en ORDER BY
-- ✅ Esto funciona perfectamente
SELECT developer, COUNT(*) AS total
FROM videogames
GROUP BY developer
ORDER BY total DESC;ORDER BY se ejecuta en el paso 6, después de SELECT (paso 5), por lo que sí puede acceder a los alias definidos ahí.
Ponlo en práctica
Usa la tabla videogames para construir consultas complejas que combinen todas las cláusulas aprendidas:
| id | title | developer | year | playtime_hours |
|---|---|---|---|---|
| 1 | The Legend of Zelda | Nintendo | 1986 | 20 |
| 2 | Super Mario Bros. | Nintendo | 1985 | 10 |
| 3 | Final Fantasy VII | Square Enix | 1997 | 40 |
| 4 | The Witcher 3 | CD Projekt Red | 2015 | 100 |
| 5 | Minecraft | Mojang Studios | 2011 | 9999 |
| 6 | Grand Theft Auto V | Rockstar Games | 2013 | 80 |
| 7 | Dark Souls | FromSoftware | 2011 | 60 |
| 8 | Portal 2 | Valve | 2011 | 8 |
| 9 | Red Dead Redemption 2 | Rockstar Games | 2018 | 70 |
| 10 | The Last of Us | Naughty Dog | 2013 | 15 |
| 11 | Halo: Combat Evolved | Bungie | 2001 | 10 |
| 12 | God of War | Santa Monica Studio | 2018 | 25 |