Subconsultas en SQL: IN, EXISTS, consultas anidadas y ejemplos prácticos


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.

  1. ejecutamos primero la consulta interna;
  2. observamos qué devuelve;
  3. 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

  1. alumnos mayores al promedio;
  2. cursos con alumnos;
  3. cursos sin alumnos;
  4. alumnos con la edad máxima;
  5. 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:

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal


Ruta SQL / MySQL

Ver todos los contenidos de SQL / MySQL

← JOIN en SQL

CREATE TABLE y ALTER TABLE →


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”

Deja un comentario

Descubre más desde Club Programador

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo