CodeGym /Cursos /SQL SELF /Comprobando la existencia de datos con EXISTS

Comprobando la existencia de datos con EXISTS y NOT EXISTS

SQL SELF
Nivel 13, Lección 3
Disponible

¡Bienvenido a una nueva lección de SQL! Hoy vamos a conocer a los operadores más discretos pero increíblemente potentesEXISTS y NOT EXISTS. Imagina a un espía que no deja huellas, pero te dice al instante: "Sí, el objeto existe" o "No, aquí no hay nada". Estos operadores no devuelven datos directamente, pero te permiten hacer comprobaciones lógicas súper precisas en tus consultas.

Vamos con lo básico. EXISTS es un operador que comprueba si existen filas en el resultado de una subconsulta. Si la subconsulta devuelve al menos una fila, la condición EXISTS devuelve TRUE, si no — FALSE.

SELECT 1
WHERE EXISTS (
    SELECT * 
    FROM students 
    WHERE grade > 3.5
);

Como ves, no nos interesan los datos de la subconsulta, solo si existen esas filas. Si hay al menos una fila que cumple la condición, la consulta devuelve 1.

Sintaxis de EXISTS

La sintaxis de EXISTS es sencilla:

SELECT columnas
FROM tabla
WHERE EXISTS (
    SELECT 1
    FROM otra_tabla
    WHERE condición
);

Explicación:

  • La subconsulta dentro de EXISTS puede ser cualquier consulta.
  • El resultado de la subconsulta es lo que determina si devuelve TRUE o FALSE.

Ejemplo: ¿Hay estudiantes con nota mayor que 4?

Imagina la tabla students:

id name grade
1 Otto 3.2
2 Anna 4.7
3 Dan 5.0
4 Lina 2.9

Supón que queremos comprobar si existen estudiantes con nota mayor que 4. Usamos esta consulta:

SELECT '¡Hay estudiantes con nota alta!'
WHERE EXISTS (
    SELECT 1
    FROM students
    WHERE grade > 4
);

Resultado:

¡Hay estudiantes con nota alta!

¿Por qué EXISTS es más rápido que IN?

La principal ventaja de EXISTS es que para la ejecución de la subconsulta en cuanto encuentra la primera coincidencia. O sea, si tienes una condición que solo quiere saber si existen datos, EXISTS puede ser súper eficiente.

Por ejemplo, imagina que la tabla students tiene millones de filas, pero solo buscas una coincidencia (grade > 4). En cuanto SQL encuentra la primera fila que cumple, la consulta termina.

Uso de NOT EXISTS

Ahora hablemos de NOT EXISTS. Este operador es el opuesto de EXISTS. Devuelve TRUE si la subconsulta no devuelve ninguna fila.

Ejemplo: encontrar estudiantes sin notas (NULL)

Supón que en nuestra tabla hay estudiantes que aún no tienen nota:

id name grade
1 Otto NULL
2 Anna 4.7
3 Dan 5.0
4 Lina NULL

Queremos seleccionar todos los estudiantes sin nota. Usamos NOT EXISTS:

SELECT *
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM students 
    WHERE grade IS NOT NULL
    AND id = s.id
);

Resultado:

id name grade
1 Otto NULL
4 Lina NULL

Comparando EXISTS y IN

A veces parece que EXISTS y IN hacen lo mismo. A primera vista sí, pero hay matices. Sobre todo si aparece un NULL por ahí. Entonces el comportamiento de IN puede ser inesperado, y EXISTS te salva.

Vamos a verlo con un ejemplo.

Tabla courses (cursos que puedes hacer):

course_id name
1 Matemáticas
2 Historia

Y los estudiantes:

student_id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

Tabla enrollments (quién se ha apuntado a qué curso):

student_id course_id
1 1
2 2
3 NULL

Queremos seleccionar los nombres de los cursos en los que alguien está apuntado. Parece fácil.

Usando IN:

SELECT name
FROM courses
WHERE course_id IN (
    SELECT course_id 
    FROM enrollments
);

Parece que debería funcionar. Pero si en enrollments hay un NULL en courseid, como con Maria Chi, IN puede devolver... ¡nada! Porque NULL hace que la subconsulta sea "indefinida", y SQL se lía: ¿y si NULL es justo el courseid que buscamos?

Usando EXISTS:

SELECT name
FROM courses c
WHERE EXISTS (
SELECT 1
FROM enrollments e
WHERE c.course_id = e.course_id
);

Pero EXISTS comprueba: "¿Hay al menos una fila donde course_id coincide?" — y ya está. No se asusta si hay un NULL cerca, porque busca coincidencias concretas, no una lista de valores.

En resumen: si puede haber NULL en la subconsulta, mejor usa EXISTS para no llevarte sorpresas.

Ejemplos de casos reales

Tabla students:

id name
1 Alex Lin
2 Anna Song
3 Maria Chi
4 Dan Seth
5 Shadow Moon

Tabla enrollments:

student_id course_id
1 1
2 2
3 NULL

Ejemplo 1. Estudiantes apuntados a cursos

Vamos a buscar a los que ya han aparecido en algún curso (aunque sea raro, como Maria Chi):

SELECT name
FROM students s
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

Resultado:

Alex Lin
Anna Song
Maria Chi

Si el estudiante aparece de alguna forma en enrollments — sale en la consulta, aunque su course_id sea raro.

Ejemplo 2. Estudiantes sin cursos

Ahora vamos a buscar a los que solo existen en el sistema — pero no están apuntados a nada:

SELECT name
FROM students s
WHERE NOT EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE s.id = e.student_id
);

Resultado:

Dan Seth
Shadow Moon

Parece que estos dos aún no han encontrado un curso que les mole. O simplemente se les ha olvidado apuntarse :)

Ejemplo 3. Seleccionar cursos con más de 5 estudiantes registrados

Tabla courses:

course_id name
1 Matemáticas
2 Historia
3 Biología
4 Filosofía

Tabla enrollments:

student_id course_id
1 1
2 1
3 1
4 1
5 1
6 1
7 2
8 2
9 2
10 NULL

Queremos encontrar los cursos en los que hay más de cinco estudiantes apuntados. Aquí EXISTS pregunta: "¿Hay algún grupo de filas para este curso donde haya más de cinco estudiantes?"

SELECT name
FROM courses c
WHERE EXISTS (
    SELECT 1
    FROM enrollments e
    WHERE c.course_id = e.course_id
    GROUP BY e.course_id
    HAVING COUNT(*) > 5
);

Resultado:

Matemáticas

Solo el curso "Matemáticas" (course_id = 1) tiene seis estudiantes apuntados. Los demás cursos aún no son tan populares.

Errores comunes usando EXISTS y NOT EXISTS

  1. Malentender la sintaxis de la subconsulta. Siempre revisa que la subconsulta haga referencia correctamente a la tabla externa.
  2. Olvidar comprobar NULL. Incluso usando EXISTS, a veces tienes que indicar explícitamente cómo tratar los NULL.
  3. No tener un índice en los campos de la subconsulta. Esto puede hacer que la consulta sea mucho más lenta.

¡Y eso es todo por hoy! Ahora ya sabes cómo usar EXISTS y NOT EXISTS para comprobar la existencia de datos, y las diferencias entre estos operadores y IN. En la próxima lección seguiremos profundizando en subconsultas, viendo cómo usarlas en SELECT para trabajar con datos agregados.

2
Tarea
SQL SELF, nivel 13, lección 3
Bloqueada
Buscar estudiantes sin calificaciones
Buscar estudiantes sin calificaciones
2
Tarea
SQL SELF, nivel 13, lección 3
Bloqueada
Comprobación de cursos con estudiantes inscritos
Comprobación de cursos con estudiantes inscritos
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION