1. Faro

Nivel 6 · Las reglas de un UNION

La solicitud

De Tyler Morgan, Ingeniero de Datos Junior

“Estoy construyendo un directorio de contactos con clientes y personal en una sola lista. Antes de publicarlo: ¿esta consulta siquiera se ejecuta, y cómo se llamarán las columnas?”

Tu objetivo

Lee la consulta de la pregunta y elige la afirmación que describe correctamente lo que hace.

¿Qué pasa cuando ejecutas esta consulta? SELECT customer_id AS id, 'customer' AS kind FROM customers UNION ALL SELECT employee_id AS staff_id, 'employee' AS kind FROM employees ORDER BY id;

Elige una respuesta y luego compruébala.

La lección

Toda operación de conjuntos, UNION ALL, UNION, INTERSECT y EXCEPT, sigue el mismo pequeño conjunto de reglas. Son fáciles de enunciar y fáciles de olvidar cuando una consulta crece hasta cinco ramas.

Regla 1: el mismo número de columnas

Cada SELECT debe devolver el mismo número de columnas. Esto falla antes de leer ningún dato:

SELECT customer_id, email FROM customers
UNION ALL
SELECT employee_id FROM employees;
-- Binder Error: Set operations can only apply to expressions
-- with the same number of result columns

Si una fuente carece de una columna, rellena el hueco explícitamente con NULL AS email o una constante.

Regla 2: emparejadas por posición, los tipos deben ser compatibles

La base de datos empareja la primera columna de cada rama, luego la segunda, y así sucesivamente. Los nombres no intervienen. Los tipos de cada posición deben ser compatibles: apilar signup_date (DATE) sobre salary (INTEGER) es un error. Los tipos compatibles pero distintos, como un entero y un decimal, se amplían al tipo mayor.

El caso peligroso son dos columnas del mismo tipo en orden intercambiado, por ejemplo units, revenue en una rama y revenue, units en la otra. Nada da error, y el resultado está mal. Alinea tus ramas visualmente, una columna por línea, para que un intercambio se vea fácil.

Regla 3: los nombres vienen del primer SELECT

Las columnas del resultado se nombran según el primer SELECT. Los alias de las ramas posteriores se ignoran, por eso la primera rama debería llevar todos los alias y las demás pueden omitirlos. Refiérete a esos nombres de la primera rama en el ORDER BY final.

Regla 4: un solo ORDER BY, al final

ORDER BY (y LIMIT) después del último SELECT se aplican a todo el resultado combinado. Para ordenar o limitar una sola rama, envuélvela primero entre paréntesis o en una subconsulta.

En Harbor & Pine, la consulta del quiz apila 2,018 clientes y 60 empleados en 2,078 filas, ordenadas por id, así que el cliente 1 y el empleado 1 quedan juntos. La columna kind es lo que los mantiene separados.

Errores comunes

  • Suponer que se requieren alias coincidentes, y renombrar las columnas en cada rama “por si acaso”.
  • Ordenar por el alias de una rama posterior. DuckDB lo tolera, pero Postgres y SQL Server esperan los nombres del primer SELECT, así que el código que depende de ello se rompe al moverse.
  • Dejar que el motor convierta en silencio. DuckDB apilará el número 1 sobre el texto 'x' convirtiendo ambos a texto. Otras bases de datos dan error. Convierte explícitamente para que la intención quede clara.

En SQL Server

Se aplican las mismas cuatro reglas. SQL Server es más estricto con los tipos: apilar un INT sobre un valor de texto no numérico falla con un error de conversión. Las etiquetas de texto suelen construirse con +, por ejemplo 'Customer ' + CAST(customer_id AS varchar(10)), donde DuckDB usa ||.

Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.