sqlpostgresqlunionmysql

UNION y UNION ALL en SQL: combinar resultados de consultas

En que se diferencian UNION y UNION ALL, que reglas de compatibilidad de columnas debes seguir y como ordenar el resultado combinado.

2 min de lecturaReferencesql · postgresql · union · mysql · clickhouse

UNION y UNION ALL apilan verticalmente los resultados de dos o mas SELECT: las filas de una consulta se anaden debajo de las de otra. La diferencia es una sola palabra clave, pero define tanto la correccion como el rendimiento.

UNION frente a UNION ALL

UNION ALL simplemente concatena los conjuntos de filas y no comprueba nada respecto a las repeticiones. UNION ademas elimina los duplicados y, para encontrarlos, el motor debe ordenar o aplicar hash a todo el resultado.

-- Keeps every row, including duplicates. Fast.
SELECT country FROM users
UNION ALL
SELECT country FROM users;

-- Collapses identical rows into one. Extra dedup pass.
SELECT country FROM users
UNION
SELECT country FROM users;

Regla practica: si ya sabes que las entradas no se solapan (por ejemplo, apilas pedidos de meses distintos), usa UNION ALL. La deduplicacion extra sobre millones de filas cuesta segundos reales de CPU y memoria para la ordenacion.

  • UNION ALL — sin deduplicacion, el orden de las filas no esta garantizado, pero suele ser mas barato.
  • UNION — deduplica sobre todo el conjunto de columnas, no solo la primera.
  • Un duplicado es una fila que coincide por completo; aqui NULL es igual a NULL (a diferencia de la comparacion normal).

Reglas de compatibilidad de columnas

Solo puedes combinar consultas con el mismo numero de columnas y tipos compatibles. Los nombres de columna provienen del primer SELECT; el resto se ignoran.

-- OK: same arity, compatible types
SELECT id, email FROM users
UNION ALL
SELECT user_id, status FROM orders;

-- Fails: 2 columns vs 3 columns
SELECT id, email FROM users
UNION ALL
SELECT id, user_id, amount FROM orders;

Si los tipos difieren, alinealos de forma explicita con CAST en lugar de confiar en la conversion implicita. Para que una pila heterogenea tenga sentido, anade una columna de origen:

SELECT id, name, CAST(NULL AS numeric) AS amount, 'user' AS source
FROM users
UNION ALL
SELECT id, CAST(NULL AS text), amount, 'order'
FROM orders;

ORDER BY y LIMIT sobre la union

ORDER BY se aplica a todo el resultado y se escribe una sola vez, al final. Ordenar ramas individuales no sirve de nada: UNION puede reorganizar las filas de todos modos.

SELECT id, name, salary FROM employees WHERE dept = 'eng'
UNION ALL
SELECT id, name, salary FROM employees WHERE dept = 'sales'
ORDER BY salary DESC
LIMIT 10;

Si necesitas ordenar o limitar una rama concreta, envuelvela en parentesis y una subconsulta:

SELECT * FROM (
  SELECT id, amount FROM orders WHERE status = 'paid'
  ORDER BY amount DESC LIMIT 5
) AS top_paid
UNION ALL
SELECT id, amount FROM orders WHERE status = 'refunded';

Trampa: el ORDER BY final ordena por posicion de columna o por el nombre del primer SELECT. Si las ramas nombran las columnas de forma distinta, usa el nombre de la primera rama o el numero de posicion (ORDER BY 3).

Diferencias entre motores

  • PostgreSQL — comprobacion estricta de tipos; UNION usa un Sort o un Hash Aggregate, visible en EXPLAIN.
  • MySQL — permite mas conversiones implicitas y a veces trunca valores en silencio; pon el ORDER BY/LIMIT de una rama en una subconsulta o se ignorara.
  • ClickHouse — por defecto UNION sin ALL puede requerir configuracion explicita; aqui casi siempre se escribe UNION ALL y la deduplicacion se hace con DISTINCT o agregados.

En resumen: UNION ALL es la opcion por defecto por velocidad, y recurres a UNION de forma deliberada, solo cuando las repeticiones realmente deben colapsarse.

Practica con ejercicios reales

Resuelve ejercicios en el entrenador de SQL con corrección instantánea y pistas.

Abrir el entrenador