Una subconsulta es una consulta que aparece dentro de otra consulta. Se utiliza cuando necesitamos calcular un valor o conjunto intermedio para resolver una consulta principal.
¿Qué problema resuelve?
Supongamos que queremos mostrar alumnos mayores que la edad promedio. Primero necesitamos conocer el promedio y luego compararlo con cada alumno.
Cómo se ejecuta mentalmente una subconsulta
Una buena forma de entenderla es leer desde adentro hacia afuera.
- ejecutamos primero la consulta interna;
- observamos qué devuelve;
- ese resultado se utiliza en la consulta externa.
Subconsulta escalar
Una subconsulta escalar devuelve un único valor.
SELECT nombre, edad FROM alumnos WHERE edad > ( SELECT AVG(edad) FROM alumnos );
Primero se calcula el promedio. Después la consulta externa compara cada edad contra ese valor.
Si el promedio fuera 22, la consulta externa se comportaría conceptualmente como si hubiéramos escrito WHERE edad > 22.
Subconsulta con IN
IN se usa cuando la subconsulta devuelve varios valores.
Si la consulta interna devuelve los ids 1, 3, 5, la condición externa equivale conceptualmente a curso_id IN (1, 3, 5).
SELECT nombre, apellido FROM alumnos WHERE curso_id IN ( SELECT id FROM cursos WHERE nombre LIKE '%Programación%' );
NOT IN
Excluye los valores devueltos por la subconsulta.
SELECT nombre, apellido FROM alumnos WHERE curso_id NOT IN ( SELECT id FROM cursos WHERE nombre = 'Bases de Datos' );
Hay que tener cuidado con NULL porque puede cambiar el resultado esperado.
Si la subconsulta de un NOT IN devuelve algún NULL, la lógica de tres valores de SQL puede hacer que no obtengamos filas. Para búsquedas de ausencia, NOT EXISTS suele ser más seguro y más expresivo.
EXISTS
EXISTS no necesita devolver un valor concreto: solo pregunta si existe al menos una fila.
Por eso suele escribirse SELECT 1: el valor concreto no importa. EXISTS se fija únicamente en si la subconsulta encontró o no una fila.
SELECT c.nombre FROM cursos AS c WHERE EXISTS ( SELECT 1 FROM alumnos AS a WHERE a.curso_id = c.id );
NOT EXISTS
Sirve para buscar casos en los que no existe relación.
SELECT c.nombre FROM cursos AS c WHERE NOT EXISTS ( SELECT 1 FROM alumnos AS a WHERE a.curso_id = c.id );
Subconsulta correlacionada
Una subconsulta correlacionada usa valores de la fila que está procesando la consulta externa.
SELECT a.nombre, a.edad FROM alumnos AS a WHERE a.edad > ( SELECT AVG(a2.edad) FROM alumnos AS a2 WHERE a2.curso_id = a.curso_id );
Aquí el promedio se calcula para el curso correspondiente a cada alumno.
Eso significa que la subconsulta depende de la fila externa. Conceptualmente puede ejecutarse muchas veces, una por cada alumno evaluado, aunque el optimizador puede aplicar estrategias internas para resolverla mejor.
Subconsulta dentro de SELECT
SELECT c.nombre, ( SELECT COUNT(*) FROM alumnos AS a WHERE a.curso_id = c.id ) AS cantidad_alumnos FROM cursos AS c;
Subconsulta dentro de FROM
La consulta interna se comporta como una tabla derivada.
SELECT datos.promedio FROM ( SELECT AVG(edad) AS promedio FROM alumnos ) AS datos;
Cuándo una subconsulta devuelve demasiadas filas
Si usamos un operador que espera un único valor, como =, pero la subconsulta devuelve varias filas, MySQL generará un error.
En esos casos debemos usar un operador adecuado, como IN, o reformular la consulta.
Probar la subconsulta por separado
Cuando una consulta anidada no funciona, una técnica muy útil es ejecutar primero solo la parte interna. Así comprobamos qué columnas y cuántas filas devuelve antes de integrarla.
JOIN o subconsulta
Muchas consultas pueden resolverse de ambas formas. Conviene priorizar claridad, mantenibilidad y rendimiento.
Por ejemplo, “cursos con alumnos” puede resolverse con EXISTS o con INNER JOIN. Ninguna forma es siempre mejor: depende del problema y del plan de ejecución.
Errores comunes
- usar = cuando la subconsulta devuelve varias filas;
- usar NOT IN sin pensar en NULL;
- crear subconsultas innecesariamente complejas;
- no probar primero la consulta interna por separado.
Ejercicios
- alumnos mayores al promedio;
- cursos con alumnos;
- cursos sin alumnos;
- alumnos con la edad máxima;
- alumnos mayores al promedio de su curso.
¿Qué sigue?
Creación y modificación de tablas.
¿Te sirvió esta guía? ☕
Si este contenido te ayudó y querés apoyar a Club Programador para seguir publicando ejercicios, proyectos y guías gratuitas, podés colaborar mediante:
Ruta SQL / MySQL
Ver todos los contenidos de SQL / MySQL
Descubre más desde Club Programador
Suscríbete y recibe las últimas entradas en tu correo electrónico.
2 opiniones en “Subconsultas en SQL: IN, EXISTS, consultas anidadas y ejemplos prácticos”