Operaciones con conjuntos de datos
Lección 5.10 · Tiempo de lectura: ~8 min · Tareas de práctica ↓
Esta lección presenta las operaciones con conjuntos de datos en SQL. Aprenderás a combinar los resultados de varias consultas, encontrar filas comunes y excluir los valores que no necesitas. Veremos UNION, UNION ALL, INTERSECT y EXCEPT con ejemplos de Sakila. Al terminar, sabrás elegir el operador adecuado para distintos escenarios analíticos.
En las lecciones anteriores aprendiste a unir tablas con JOIN y cómo ejecuta el motor esas uniones. Ahora pasamos a otra idea: a veces no quieres relacionar filas por claves, sino combinar y comparar conjuntos de resultados completos.
Las operaciones con conjuntos son útiles cuando quieres juntar datos de varias consultas, encontrar la intersección entre dos públicos o quitar las filas que ya aparecen en otra lista. En la práctica esto aparece a menudo en informes, controles de calidad de datos y en la preparación de listas finales.
Qué son las operaciones con conjuntos de datos
Las operaciones con conjuntos no trabajan con filas de una sola tabla, sino con los resultados de dos o más consultas. En términos de SQL, cada SELECT devuelve un conjunto de filas, y operadores como UNION o INTERSECT combinan esos conjuntos según reglas concretas.
Los cuatro operadores más usados son:
UNION: combina los resultados y elimina los duplicados;UNION ALL: combina los resultados y conserva los duplicados;INTERSECT: deja solo las filas que aparecen en los dos conjuntos;EXCEPT: devuelve las filas del primer conjunto que no existen en el segundo.
Importante: no todas las bases de datos admiten estos operadores exactamente igual. Cuando lleves consultas de un motor a otro, comprueba siempre la versión y la compatibilidad.
Reglas generales
Para usar una operación de conjuntos, las dos consultas SELECT deben devolver resultados compatibles.
Requisitos de las consultas
- el mismo número de columnas;
- tipos de datos compatibles en las posiciones correspondientes;
- el mismo orden de columnas;
- en lo posible, el mismo significado de los valores.
Si necesitas ordenar el resultado final, escribe ORDER BY al final de toda la expresión.
SELECT column1, column2
FROM table_a
UNION
SELECT column1, column2
FROM table_b
ORDER BY column1;
UNION y UNION ALL
UNION y UNION ALL se parecen, pero resuelven problemas distintos.
UNIONelimina los duplicados del resultado final.UNION ALLconserva todas las filas, aunque se repitan.
Ejemplo: una lista de ciudades de clientes y empleados
Supongamos que queremos una sola lista de las ciudades donde viven los clientes y los empleados de Sakila.
SELECT
ci.city
FROM customer AS c
JOIN address AS a ON c.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
UNION
SELECT
ci.city
FROM staff AS s
JOIN address AS a ON s.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
ORDER BY city;
Resultado: obtienes una lista de ciudades sin duplicados, aunque clientes y empleados vivan en la misma ciudad.
Si quieres conservar todas las filas de ambas fuentes, usa UNION ALL:
SELECT
ci.city
FROM customer AS c
JOIN address AS a ON c.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
UNION ALL
SELECT
ci.city
FROM staff AS s
JOIN address AS a ON s.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
ORDER BY city;
Nota: UNION ALL es útil cuando los duplicados tienen significado, por ejemplo si después vas a contar las filas de la lista combinada.
Cuándo elegir UNION ALL
UNION ALL suele ser más rápido que UNION, porque la base de datos no dedica tiempo a eliminar duplicados. Así que, si no necesitas unicidad, UNION ALL suele ser la mejor opción.
INTERSECT
INTERSECT devuelve solo las filas que aparecen en los dos conjuntos de resultados. Es útil cuando necesitas la parte común de dos listas.
Ejemplo: ciudades donde viven tanto clientes como empleados
SELECT
ci.city
FROM customer AS c
JOIN address AS a ON c.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
INTERSECT
SELECT
ci.city
FROM staff AS s
JOIN address AS a ON s.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
ORDER BY city;
Resultado: ves solo las ciudades que aparecen tanto entre los clientes como entre los empleados.
Dónde resulta útil
INTERSECT sirve para encontrar el segmento común entre dos públicos, comparar listas de sistemas distintos o comprobar si dos extracciones se solapan.
EXCEPT
EXCEPT devuelve las filas del primer conjunto que no existen en el segundo. Es el operador de diferencia de conjuntos.
Ejemplo: ciudades donde viven clientes pero no empleados
SELECT
ci.city
FROM customer AS c
JOIN address AS a ON c.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
EXCEPT
SELECT
ci.city
FROM staff AS s
JOIN address AS a ON s.address_id = a.address_id
JOIN city AS ci ON a.city_id = ci.city_id
ORDER BY city;
Resultado: obtienes la lista de ciudades donde hay clientes pero no empleados.
Nota importante
En algunas bases de datos EXCEPT se llama MINUS o solo está disponible en determinadas versiones. Si escribes SQL portable, conviene comprobarlo por separado.
Uso práctico
Las operaciones con conjuntos son especialmente útiles en analítica y en la validación de datos.
UNIONayuda a construir una lista de referencia a partir de varias fuentes.UNION ALLsirve para combinar flujos de datos antes de agregarlos.INTERSECTmuestra la parte común o las filas que coinciden.EXCEPTayuda a encontrar discrepancias, huecos y valores sobrantes.
A veces las operaciones con conjuntos se pueden sustituir por JOIN, pero no siempre es cómodo. Si necesitas comparar resultados de consultas en lugar de relacionar tablas por claves, las operaciones con conjuntos suelen ser más fáciles de leer.
Cuándo conviene reescribir varias condiciones OR con UNION
A veces una cláusula WHERE larga con varias condiciones OR se vuelve difícil de leer y mantener. En ese caso puedes dividir la lógica en ramas separadas y combinarlas con UNION.
Este enfoque es especialmente útil cuando:
- cada rama representa una regla de negocio distinta;
- las condiciones tienen significados muy diferentes;
- quieres que la consulta sea más fácil de leer y mantener.
Ejemplo: encontrar las películas que tienen clasificación R o que duran más de 180 minutos.
SELECT
title,
rating,
length
FROM film
WHERE rating = 'R'
UNION
SELECT
title,
rating,
length
FROM film
WHERE length > 180
ORDER BY title;
Resultado: en lugar de una cláusula larga WHERE ... OR ..., tienes dos consultas claras que son más fáciles de leer, cambiar y probar. Si una fila cumple las dos ramas, UNION elimina el duplicado automáticamente. Si los duplicados no son un problema y las ramas no se solapan, puedes usar UNION ALL.
Nota: si las condiciones se aplican a la misma columna, a menudo basta con IN (...). UNION es más útil cuando las ramas son lógicamente distintas o dependen de columnas diferentes.
Preguntas frecuentes
¿MySQL admite INTERSECT y EXCEPT?
Sí, desde MySQL 8.0.31; MariaDB los admite desde la versión 10.3. En versiones anteriores, INTERSECT se escribe con IN, EXISTS o un INNER JOIN, y EXCEPT con NOT EXISTS o LEFT JOIN ... WHERE ... IS NULL. Oracle tradicionalmente usa MINUS en lugar de EXCEPT.
¿Qué nombres de columna tiene el resultado de un UNION?
Los nombres vienen del primer SELECT. Los alias de la segunda consulta y las siguientes se ignoran, así que da a las columnas sus nombres finales en la primera consulta. El ORDER BY al final de la sentencia usa esos nombres.
¿Cómo ordenar o limitar solo una parte de un UNION?
Pon ese SELECT entre paréntesis: (SELECT title FROM film ORDER BY length DESC LIMIT 5) UNION ALL (SELECT ...). Sin paréntesis, ORDER BY y LIMIT se aplican a todo el resultado combinado. Un ORDER BY dentro de una parte sin LIMIT puede ignorarse, porque el orden del conjunto final no está garantizado de todos modos.
Preguntas de entrevista
¿Qué diferencia hay entre UNION y UNION ALL?
UNION combina los resultados de dos consultas y elimina los duplicados, mientras que UNION ALL conserva todas las filas. En la práctica, UNION ALL suele ser más rápido, porque no hace el trabajo extra de buscar repeticiones.
¿Por qué las operaciones de conjuntos exigen consultas SELECT compatibles?
Porque SQL combina los resultados por la posición de las columnas, no por su nombre. Si dos consultas devuelven distinto número de columnas o tipos de datos incompatibles, la base de datos no puede construir un conjunto final válido.
¿Cuándo usar INTERSECT y cuándo EXCEPT?
INTERSECT es la mejor opción cuando necesitas las filas que aparecen en las dos listas. EXCEPT es útil cuando quieres restar la segunda lista de la primera y quedarte solo con los valores restantes.
¿En qué se diferencian las operaciones de conjuntos de JOIN?
JOIN relaciona filas por claves y normalmente añade columnas de otra tabla. Las operaciones de conjuntos trabajan con resultados de consultas completos y los comparan como conjuntos, lo que es útil para combinar listas, encontrar coincidencias e identificar diferencias.
Puntos clave de esta lección
UNIONcombina los resultados y elimina los duplicados.UNION ALLcombina los resultados sin eliminar duplicados.INTERSECTdeja solo las filas comunes a los dos conjuntos.EXCEPTdevuelve las filas que existen en el primer conjunto pero no en el segundo.- Todas las operaciones de conjuntos exigen consultas
SELECTcompatibles con el mismo número de columnas. - El
ORDER BYdel resultado final debe ir al final de toda la expresión. - En la analítica práctica, estas operaciones sirven para juntar listas, encontrar coincidencias y comparar datos entre fuentes.