Subconsultas: consultas dentro de consultas
Una subconsulta es una consulta SELECT dentro de otra consulta SQL. Se escribe entre paréntesis y se ejecuta primero: su resultado se usa en la consulta exterior.
Subconsultas en WHERE
El uso más común es dentro de WHERE para comparar con un valor calculado dinámicamente:
SELECT title, year
FROM videogames
WHERE year = (SELECT MAX(year) FROM videogames);La subconsulta devuelve 2018 (el año más reciente) y la consulta externa filtra los juegos de ese año.
Subconsultas con IN
Cuando la subconsulta devuelve múltiples filas, usa IN en vez de =:
SELECT title, developer
FROM videogames
WHERE developer IN (
SELECT developer
FROM videogames
GROUP BY developer
HAVING COUNT(*) > 1
);Primero se obtienen los desarrolladores con más de un juego (Nintendo, Rockstar Games), y luego se filtran todos sus juegos.
Subconsultas en SELECT
Puedes usar una subconsulta como columna calculada en SELECT:
SELECT title,
playtime_hours,
(SELECT MAX(playtime_hours) FROM videogames) AS max_horas
FROM videogames;Cada fila mostrará sus horas de juego junto al máximo global, lo que permite comparar fácilmente cada juego con el récord.
EXISTS y NOT EXISTS
EXISTS comprueba si una subconsulta devuelve al menos una fila. Es diferente de IN: no compara valores, sino que verifica la existencia de resultados.
SELECT title
FROM videogames v
WHERE EXISTS (
SELECT 1
FROM videogames v2
WHERE v2.developer = v.developer
AND v2.id != v.id
);Esta consulta devuelve los juegos cuyo desarrollador tiene al menos otro juego en la tabla. La subconsulta usa SELECT 1 porque no importa qué valor devuelve, solo si hay filas o no.
NOT EXISTS hace lo contrario: devuelve las filas donde la subconsulta no encuentra resultados:
SELECT title, developer
FROM videogames v
WHERE NOT EXISTS (
SELECT 1
FROM videogames v2
WHERE v2.developer = v.developer
AND v2.id != v.id
);Esto devuelve juegos cuyo desarrollador solo tiene un juego en la tabla (no existe otro juego del mismo developer).
EXISTS vs IN
Ambos pueden resolver problemas similares, pero tienen diferencias:
INcompara un valor contra una lista de valores devuelta por la subconsulta.EXISTSsolo comprueba si la subconsulta tiene resultados, sin comparar valores concretos.EXISTSsuele ser más eficiente con subconsultas correlacionadas (que referencian la consulta exterior).
Reglas clave
- La subconsulta siempre va entre paréntesis
( ). - Se ejecuta primero, antes que la consulta exterior (excepto en subconsultas correlacionadas con
EXISTS, que se evalúan fila a fila). - Con
=,>,<, la subconsulta debe devolver un solo valor (subconsulta escalar). - Con
IN, puede devolver múltiples valores. - Con
EXISTS, solo importa si la subconsulta devuelve alguna fila.
Tip: Muchas subconsultas en
WHEREpueden reescribirse comoJOIN. Usa subconsultas cuando la lógica sea más clara o necesites un valor agregado para comparar.
Nuestra tabla
| 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 |