Aprende SQL

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.

Consulta con subconsulta
SELECT title, year
FROM videogames
WHERE year =
subconsulta
SELECT MAX(year)
FROM videogames
se evalúa
Se resuelve a
SELECT title, year
FROM videogames
WHERE year = 2018
Resultado
Red Dead Redemption 22018
God of War2018

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:

  • IN compara un valor contra una lista de valores devuelta por la subconsulta.
  • EXISTS solo comprueba si la subconsulta tiene resultados, sin comparar valores concretos.
  • EXISTS suele 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 WHERE pueden reescribirse como JOIN. Usa subconsultas cuando la lógica sea más clara o necesites un valor agregado para comparar.

Nuestra tabla

Nombre de la Tabla: videogames
idtitledeveloperyearplaytime_hours
1The Legend of ZeldaNintendo198620
2Super Mario Bros.Nintendo198510
3Final Fantasy VIISquare Enix199740
4The Witcher 3CD Projekt Red2015100
5MinecraftMojang Studios20119999
6Grand Theft Auto VRockstar Games201380
7Dark SoulsFromSoftware201160
8Portal 2Valve20118
9Red Dead Redemption 2Rockstar Games201870
10The Last of UsNaughty Dog201315
11Halo: Combat EvolvedBungie200110
12God of WarSanta Monica Studio201825

Ejercicios