UNION, INTERSECT y EXCEPT
IntermedioLos operadores de conjuntos combinan resultados completos. UNION ALL apila las filas tal cual y UNION apila y además quita repetidos. INTERSECT deja las filas que están en los dos resultados y EXCEPT las del primero que no están en el segundo. Los dos lados deben tener la misma cantidad de columnas, con tipos compatibles y en el mismo orden.
Sintaxis
SELECT columna FROM tabla_a
UNION ALL -- o UNION, INTERSECT, EXCEPT
SELECT columna FROM tabla_b
ORDER BY columna; -- ordena el resultado combinadoEjemplo
WITH siguen AS (
SELECT f.user_id
FROM follows AS f
INNER JOIN users AS u ON u.id = f.user_id
WHERE u.country = 'CL'
),
crean_listas AS (
SELECT p.user_id
FROM playlists AS p
INNER JOIN users AS u ON u.id = p.user_id
WHERE u.country = 'CL'
)
SELECT 'UNION ALL' AS operacion, count(*) AS filas
FROM (SELECT user_id FROM siguen UNION ALL SELECT user_id FROM crean_listas) AS x
UNION ALL
SELECT 'UNION', count(*)
FROM (SELECT user_id FROM siguen UNION SELECT user_id FROM crean_listas) AS x
UNION ALL
SELECT 'INTERSECT', count(*)
FROM (SELECT user_id FROM siguen INTERSECT SELECT user_id FROM crean_listas) AS x
UNION ALL
SELECT 'EXCEPT', count(*)
FROM (SELECT user_id FROM siguen EXCEPT SELECT user_id FROM crean_listas) AS x
ORDER BY filas DESC;Resultado
| operacion | filas |
|---|---|
| UNION ALL | 1819 |
| UNION | 470 |
| EXCEPT | 267 |
| INTERSECT | 200 |
Cómo leerlo
En Chile hay 1475 seguimientos de artistas y 344 listas creadas: UNION ALL suma las 1819 filas con repetidos. UNION deja 470 oyentes distintos que hicieron al menos una de las dos cosas. 200 hicieron las dos (INTERSECT) y 267 siguen artistas pero nunca crearon una lista (EXCEPT). UNION, INTERSECT y EXCEPT quitan repetidos.
Error común
Así no
SELECT user_id FROM follows
UNION
SELECT user_id FROM playlists;Usar UNION cuando se quieren conservar todas las filas, o por costumbre. UNION elimina repetidos: si cada fila representa un evento (un pago, una reproducción), se pierden eventos y los totales quedan cortos. Además, quitar repetidos obliga al motor a ordenar o comparar todo el resultado. Si no necesitas deduplicar, usa UNION ALL.
En otros motores: BigQuery, Oracle, Snowflake, MySQL
BigQuery
No acepta
UNIONa secas: hay que escribirUNION ALLoUNION DISTINCT. Lo mismo conINTERSECT DISTINCTyEXCEPT DISTINCT.SELECT user_id FROM follows UNION DISTINCT SELECT user_id FROM playlists;Oracle
La diferencia se escribe tradicionalmente
MINUS. Las versiones recientes (21c en adelante) aceptan tambiénEXCEPT.Snowflake
Acepta
EXCEPTy tambiénMINUScomo sinónimo.MySQL
INTERSECTyEXCEPTexisten desde la versión 8.0.31. En versiones anteriores se resuelven conEXISTSyNOT EXISTS.
Estos fragmentos no se ejecutan en el curso: se muestran como referencia de cada motor.