SQL IN: filtrado de filas basado en listas
El operador SQL IN comprueba si un valor coincide con algún elemento de una lista. Un predicado SQL WHERE IN reemplaza cadenas largas de OR al filtrar por un conjunto conocido de valores discretos: códigos de estado, nombres de categoría, IDs de región. Usa una lista SQL WHERE IN cuando los valores se conocen de antemano y la condición debe seguir siendo legible a medida que crece.
Ejemplo de SQL IN para coincidencia por lista
Salida:
La salida aparecerá aquí...
Salida:
+----------+-------------+
| name | category |
+----------+-------------+
| Borrador | papeleria |
| Cuaderno | papeleria |
| Raton | electronica |
| Teclado | electronica |
+----------+-------------+
4 row(s)
Cómo funciona este ejemplo
CREATE TABLEeINSERTrellenan una tablaproductscon cinco filas repartidas en tres categorías.WHERE category IN ('electronica', 'papeleria')coincide con cualquier fila cuyocategorysea igual a uno de los valores listados. En términos lógicos, equivale acategory = 'electronica' OR category = 'papeleria'.- La fila de
mueblesse excluye porque sucategoryno está en la lista. ORDER BY namehace que la salida sea determinista.
IN con una lista literal es equivalente a encadenar comparaciones con OR, pero escala mejor cuando el conjunto crece: agregar un valor significa sumar un elemento a la lista, no otra cláusula OR.
¿Qué es el operador SQL IN?
El operador SQL IN es una forma abreviada de múltiples comparaciones de igualdad unidas con OR. WHERE x IN (a, b, c) es lógicamente idéntico a WHERE x = a OR x = b OR x = c. Bajo la lógica ternaria de SQL, si ningún elemento de la lista coincide y ningún elemento es NULL, IN devuelve falso. Si algún elemento es NULL y no existe coincidencia exacta, el resultado es desconocido; en una cláusula WHERE, desconocido filtra la fila.
Cómo manejar una lista vacía en SQL WHERE IN
La mayoría de bases de datos rechazan WHERE col IN () con un error de sintaxis, algo común al generar una lista SQL WHERE IN de forma dinámica. Maneja el caso vacío de forma explícita: omite el filtro o fuerza un predicado siempre falso como WHERE 1 = 0 cuando una lista vacía debe devolver cero filas.
SQL NOT IN y la trampa de NULL
SQL NOT IN invierte la comprobación: devuelve true solo cuando el valor es distinto de todos los elementos de la lista. Un solo NULL en la lista puede cambiar el resultado a desconocido porque x <> NULL siempre es desconocido, y WHERE trata desconocido como falso:
-- Devuelve 0 filas: el NULL vuelve el predicado DESCONOCIDO
SELECT name
FROM products
WHERE category NOT IN ('electronica', NULL);
Cuando la lista viene de una subconsulta, filtra los NULL dentro de la subconsulta o usa NOT EXISTS para una semántica segura frente a NULL.
IN con subconsultas
IN también acepta una subconsulta en lugar de una lista literal. Conceptualmente, la subconsulta produce un conjunto de valores y la consulta externa comprueba pertenencia:
SELECT name FROM products
WHERE category IN (
SELECT category FROM products WHERE name LIKE '%ado%'
);
Para subconsultas pequeñas y no correlacionadas, funciona bien. Cuando la subconsulta devuelve muchas filas o implica correlación, un predicado EXISTS o un JOIN suele rendir mejor porque el optimizador puede aplicar estrategias de semi-join.
IN vs EXISTS vs JOIN
| Enfoque | Úsalo cuando… |
|---|---|
IN (list) | Filtras por un conjunto pequeño y conocido de valores literales |
IN (subquery) | Compruebas pertenencia contra un conjunto pequeño de resultados no nulos |
EXISTS (subquery) | Necesitas una comprobación correlacionada o claves foráneas anulables |
JOIN | Necesitas columnas de ambas tablas en el resultado |
BETWEEN | Los valores forman un rango continuo, no elementos discretos |
Regla: usa IN para conjuntos de valores discretos. Cambia a EXISTS cuando la subconsulta sea correlacionada o anulable. Usa un JOIN cuando necesites datos de ambos lados.
Notas de rendimiento
IN sobre una columna indexada es sargable: el optimizador puede hacer búsquedas por índice para cada valor de la lista. Algunos motores ordenan internamente las listas IN literales para evaluarlas con búsqueda binaria. Las listas literales muy grandes (cientos de valores) pueden ralentizar el análisis y la generación del plan; carga esos valores en una tabla temporal y usa JOIN.
FAQ
¿SQL IN es lo mismo que varias condiciones OR?
En términos lógicos, sí. WHERE x IN (1, 2, 3) equivale a WHERE x = 1 OR x = 2 OR x = 3. El optimizador suele producir el mismo plan de ejecución para ambas formas, pero IN es más corto y más fácil de mantener a medida que la lista crece.
¿Por qué NOT IN no devuelve filas cuando la subconsulta contiene NULL?
NOT IN se expande a una cadena de comparaciones con AND: x <> a AND x <> b AND x <> NULL. Como x <> NULL siempre es desconocido, toda la expresión nunca es verdadera. Filtra los NULL de la subconsulta o usa NOT EXISTS para evitarlo.
¿Puedo usar IN con una subconsulta?
Sí. WHERE col IN (SELECT col FROM other_table) comprueba pertenencia contra el resultado de la subconsulta. Para conjuntos pequeños y no anulables, esto es eficiente. Para conjuntos grandes o anulables, EXISTS o un JOIN suelen darle más flexibilidad al optimizador.