Imagina que curras en la base de datos de una uni y necesitas encontrar estudiantes que están en cursos concretos. Por ejemplo, en "Programación", "Matemáticas" y "Física". Claro, podrías escribir una consulta larguísima con un montón de condiciones tipo:
SELECT *
FROM students
WHERE course = 'Programación'
OR course = 'Matemáticas'
OR course = 'Física';
Pero seamos sinceros. Escribir esas cosas es un rollo y queda poco elegante. Por suerte, existe el operador IN, que te deja escribir la misma consulta de forma compacta y ahorrando tiempo:
SELECT *
FROM students
WHERE course IN ('Programación', 'Matemáticas', 'Física');
Suena a magia, ¿verdad? En vez de un montón de OR, simplemente le dices a SQL que busque los valores en esa lista. Y si quieres comprobar que un valor no está en la lista, usas NOT IN — Busca todo lo que no esté en esa lista.
Sintaxis del operador IN
Esta es la sintaxis general del operador IN:
SELECT columnas
FROM tabla
WHERE columna IN (valor1, valor2, valor3, ...);
Ahora vamos a ver algunos ejemplos.
Ejemplo 1: Estudiantes que estudian varios cursos
Supón que tienes la tabla students:
| id | name | course |
|---|---|---|
| 1 | Anna | Programación |
| 2 | Mello | Física |
| 3 | Kate | Matemáticas |
| 4 | Dan | Química |
| 5 | Olly | Biología |
Queremos encontrar a todos los estudiantes que estudian "Programación", "Matemáticas" o "Física". Usamos IN:
SELECT name, course
FROM students
WHERE course IN ('Programación', 'Matemáticas', 'Física');
Resultado:
| name | course |
|---|---|
| Anna | Programación |
| Mello | Física |
| Kate | Matemáticas |
Como ves, el operador IN simplifica mucho la vida. No hace falta escribir condiciones largas con OR, solo pones la lista de valores que te interesan.
Ejemplo 2: Estudiantes que no estudian ciertos cursos
Ahora, imagina que quieres encontrar estudiantes que no estudian "Programación", "Matemáticas" y "Física". Aquí viene bien el operador NOT IN:
SELECT name, course
FROM students
WHERE course NOT IN ('Programación', 'Matemáticas', 'Física');
Resultado:
| name | course |
|---|---|
| Dan | Química |
| Olly | Biología |
Así, el operador NOT IN devuelve todas las filas donde el valor de la columna course no está en la lista indicada.
Uso de IN y NOT IN con subconsultas
Los operadores IN y NOT IN son súper útiles cuando necesitas comparar datos entre dos tablas. Por ejemplo, imagina que tienes dos tablas:
Tabla students:
| id | name | course_id |
|---|---|---|
| 1 | Anna | 101 |
| 2 | Mello | 102 |
| 3 | Kate | 103 |
| 4 | Dan | 104 |
Tabla courses:
| id | name |
|---|---|
| 101 | Programación |
| 102 | Física |
| 103 | Matemáticas |
| 105 | Química |
Supón que necesitas encontrar estudiantes que están apuntados a cursos que existen en la tabla courses. Aquí te salva una subconsulta con IN:
SELECT name
FROM students
WHERE course_id IN (
SELECT id
FROM courses
);
Esta consulta funciona así: la subconsulta SELECT id FROM courses devuelve la lista de todos los IDs de cursos. Luego el operador IN comprueba si course_id está en esa lista.
Resultado:
| name |
|---|
| Anna |
| Mello |
| Kate |
¿Por qué falta Dan? Porque su course_id (104) no está en la tabla courses.
Peculiaridades al trabajar con NULL
El operador IN tiene una peculiaridad importante: si en la lista de valores hay un NULL, puede afectar al resultado de la consulta. Mira este ejemplo.
Tabla grades:
| student_id | course_id | grade |
|---|---|---|
| 1 | 101 | A |
| 2 | 102 | NULL |
| 3 | 103 | B |
Una consulta que busca estudiantes con nota en ('A', 'B', 'C') podría ser así:
SELECT student_id
FROM grades
WHERE grade IN ('A', 'B', 'C');
Resultado:
| student_id |
|---|
| 1 |
| 3 |
La fila con NULL en la columna grade se ignora, porque NULL no se considera parte de ninguna lista.
Ahora imagina que usas el operador NOT IN. Por ejemplo:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C');
Esperas ver la fila con student_id = 2, ¡pero el resultado está vacío! ¿Por qué? Porque NULL se compara con cada valor de la lista y el resultado siempre es indefinido (UNKNOWN). Este comportamiento puede despistar, así que cuando uses NOT IN, ten en cuenta si hay columnas con NULL. Lo mejor en estos casos es usar una comprobación explícita de NULL:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C')
OR grade IS NULL;
Resultado:
| student_id |
|---|
| 2 |
Consejos para usar IN y NOT IN
Usa IN para que tu código SQL sea más legible
Si necesitas comprobar si una columna está en una lista de valores, siempre es mejor usar IN que un montón de condiciones con OR.
Ojo con NOT IN y NULL
Si tienes columnas con NULL en tus datos, pueden darte resultados raros. Mejor trata NULL de forma explícita cuando uses NOT IN.
Usa índices para acelerar subconsultas
Si usas IN con una subconsulta, asegúrate de que la columna en la subconsulta esté indexada, así evitas problemas de rendimiento.
Ejemplo de un caso real
Imagina que trabajas en el sistema de una tienda online. Tienes las tablas orders y users. Quieres encontrar a todos los usuarios que nunca han hecho un pedido.
Tabla users:
| id | name |
|---|---|
| 1 | Anna |
| 2 | Mello |
| 3 | Kate |
| 4 | Dan |
Tabla orders:
| id | user_id | total |
|---|---|---|
| 1 | 1 | 500 |
| 2 | 3 | 300 |
Usamos NOT IN para resolverlo:
SELECT name
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Resultado:
| name |
|---|
| Mello |
| Dan |
Esta consulta funciona así: primero la subconsulta SELECT user_id FROM orders devuelve los IDs de todos los usuarios que han hecho pedidos (1 y 3). Luego el operador NOT IN los excluye, dejando solo a los que no han hecho pedidos (Mello y Dan).
GO TO FULL VERSION