La cláusula IN en SQL es una de las formas más prácticas y legibles de filtrar datos cuando queremos comprobar si el valor de una columna pertenece a una lista de valores o al resultado de una subconsulta.
En lugar de escribir múltiples condiciones con OR
, IN
simplifica el código y lo hace más fácil de mantener.
Por ejemplo:
-- Sin IN
SELECT * FROM clientes
WHERE ciudad = 'Madrid' OR ciudad = 'Barcelona' OR ciudad = 'Valencia';
-- Con IN
SELECT * FROM clientes
WHERE ciudad IN ('Madrid', 'Barcelona', 'Valencia');
Ambas consultas devuelven el mismo resultado, pero la segunda es más compacta y clara.
Sintaxis de IN en SQL
La forma general es:
columna IN (valor1, valor2, valor3, ...)
columna
: campo que queremos evaluar.valor1, valor2...
: la lista de valores a comparar.
También puede utilizarse con subconsultas:
columna IN (subconsulta)
Ejemplos prácticos con IN
1) Filtro con lista de valores
SELECT * FROM productos
WHERE categoria IN ('Electrónica', 'Ropa', 'Juguetes');
👉 Devuelve solo los productos cuya categoría esté en la lista.
2) Usar IN con números
SELECT * FROM empleados
WHERE departamento_id IN (1, 3, 5);
👉 Selecciona empleados de los departamentos 1, 3 y 5.
3) IN con subconsulta
SELECT * FROM clientes
WHERE id IN (SELECT cliente_id FROM pedidos WHERE total > 500);
👉 Devuelve clientes que tienen al menos un pedido de más de 500. Aquí se combinan IN y WHERE para filtrar clientes según sus pedidos.
4) Negación con NOT IN
SELECT * FROM clientes
WHERE ciudad NOT IN ('Madrid', 'Barcelona');
👉 Selecciona a los clientes cuya ciudad no sea Madrid ni Barcelona.
5) IN con fechas
SELECT * FROM ventas
WHERE fecha IN ('2025-01-01', '2025-01-15', '2025-01-31');
👉 Devuelve ventas ocurridas en días específicos.
IN vs = y OR
- =: compara un único valor.
- OR: permite varias condiciones, pero es más largo de escribir.
- IN: es la forma más simple y escalable para listas largas.
Ejemplo comparativo:
-- Con OR
WHERE estado = 'pendiente' OR estado = 'enviado' OR estado = 'cancelado';
-- Con IN
WHERE estado IN ('pendiente', 'enviado', 'cancelado');
IN con subconsultas: casos de uso
El uso de IN
con subconsultas es muy frecuente en reportes complejos.
Ejemplo:
SELECT nombre
FROM empleados
WHERE id IN (
SELECT empleado_id FROM proyectos WHERE estado = 'activo'
);
👉 Devuelve empleados que participan en proyectos activos.
También se puede usar en condiciones de JOIN o filtros intermedios.
Diferencias entre IN y EXISTS
Ambas pueden usarse con subconsultas, pero hay diferencias:
IN
: compara un valor con una lista de resultados.EXISTS
: verifica si la subconsulta devuelve alguna fila.
Ejemplo con IN
:
SELECT * FROM clientes c
WHERE c.id IN (SELECT cliente_id FROM pedidos WHERE total > 100);
Ejemplo con EXISTS
:
SELECT * FROM clientes c
WHERE EXISTS (SELECT 1 FROM pedidos p WHERE p.cliente_id = c.id AND p.total > 100);
👉 Suelen ser equivalentes, pero EXISTS es más eficiente cuando la subconsulta genera muchos registros.
Errores comunes con IN
- Usar IN con subconsultas que devuelven NULL
SELECT * FROM empleados
WHERE id IN (SELECT jefe_id FROM departamentos);
👉 Si la subconsulta devuelve algún NULL
, puede afectar el resultado.
- Listas demasiado largas en IN
Cuando se ponen cientos o miles de valores dentro deIN
, la consulta puede volverse lenta.
👉 En esos casos es mejor cargar los valores en una tabla temporal y usar unJOIN
.
- Olvidar el NOT con NOT IN
Recordar queNOT IN
se comporta distinto si hayNULL
en la lista: puede devolver 0 filas.
Ejemplo:
WHERE columna NOT IN (1,2,NULL)
👉 Esto devuelve vacío en la mayoría de SGBD.
Buenas prácticas con IN
- Usar
IN
para listas cortas y legibles (5–20 elementos). - Para listas muy largas → preferir un
JOIN
con tabla auxiliar. - Con subconsultas, verificar que no retornen
NULL
. - Para negaciones, considerar usar
NOT EXISTS
en lugar deNOT IN
.
Ejemplo avanzado: top clientes en ciudades específicas
SELECT c.nombre, SUM(p.total) AS gasto
FROM clientes c
JOIN pedidos p ON c.id = p.cliente_id
WHERE c.ciudad IN ('Madrid', 'Barcelona', 'Valencia')
GROUP BY c.nombre
HAVING SUM(p.total) > 1000
ORDER BY gasto DESC;
👉 Devuelve clientes de las tres ciudades más importantes que hayan gastado más de 1000.
Preguntas frecuentes (FAQ)
1. ¿IN es más rápido que OR?
En la mayoría de los motores, sí. SQL traduce internamente IN
en algo optimizado.
2. ¿Se puede usar IN con subconsultas correlacionadas?
Sí, aunque en algunos casos EXISTS
puede ser más eficiente.
3. ¿NOT IN puede devolver resultados inesperados?
Sí, si hay NULL
en la lista. Lo recomendable es usar NOT EXISTS
.
4. ¿Qué diferencia hay entre IN y JOIN?IN
es un filtro, JOIN
une datos. En algunos casos se pueden reemplazar, pero no siempre son equivalentes.
5. ¿Se puede usar IN con cadenas de texto y fechas?
Sí, siempre que los valores sean del mismo tipo que la columna.
Conclusión
La cláusula IN en SQL es una herramienta simple pero muy poderosa para filtrar datos en listas o basados en subconsultas. Bien combinada con SELECT, WHERE y funciones de agregación como COUNT, permite escribir consultas más claras y efectivas.
- Reemplaza múltiples condiciones
OR
. - Mejora la legibilidad de las consultas.
- Se combina muy bien con subconsultas.
Sin embargo, conviene tener en cuenta sus limitaciones: las listas muy largas afectan el rendimiento, y el uso de NOT IN
con NULL
puede generar resultados inesperados.
Aplica el operador IN
en filtros con listas y subconsultas en la lección WHERE y condiciones y revisa más definiciones en el Glosario SQL completo.