sql >> Base de Datos >  >> RDS >> Database

Cláusula SQL UNION para principiantes

En SQL, la UNION La cláusula concatena los resultados de dos consultas en un único conjunto de resultados.

Puedes usar la UNION cláusula con o sin ALL argumento:

  • UNION ALL – Incluye duplicados.
  • UNION – Excluye duplicados.

A continuación se muestran algunos ejemplos básicos para demostrar cómo funciona.

Tablas de muestra

Supongamos que tenemos dos tablas:Cats y Dogs

Cats

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
| 1002    | Fetch     |
+---------+-----------+

Podemos usar un SELECT declaración con UNION cláusula para combinar los resultados de ambas tablas en un conjunto de resultados.

Ejemplo usando UNION ALL

Primero, usemos UNION ALL para que incluya duplicados.

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultado:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

En este caso, se devuelven siete filas. Podemos ver que "Fetch" se devuelve dos veces. Esto se debe a que hay dos perros llamados Fetch.

También hay un gato y un perro con el mismo nombre:Fluffy.

Tenga en cuenta que usé un alias de columna para nombrar el campo devuelto por la operación. Si no hubiera hecho eso, el resultado habría usado los nombres de las columnas de la primera consulta. En ese caso, el encabezado de la columna se habría llamado DogName en lugar de PetName .

SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultado:

+-----------+
| DogName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

Esto puede o no ser aceptable, según los datos que devuelva en su consulta. En nuestro caso, no es apropiado, porque no todos los resultados son perros.

Ejemplo usando UNION

Veamos qué sucede cuando eliminamos ALL argumento.

SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;

Resultado:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Meow      |
| Scratch   |
| Wag       |
+-----------+
(5 rows affected)

Esta vez solo se devuelven cinco filas. Se eliminan ambos duplicados.

UNION vs DISTINCT

Tenga en cuenta que esto es diferente a aplicar DISTINCT a cada individuo SELECT declaración. Si hubiéramos hecho eso, Fluffy habría sido devuelto dos veces, porque ALL solo aplicaría para el SELECT declaración contra la que se está aplicando (no a los resultados concatenados).

Aquí hay un ejemplo para ilustrar lo que quiero decir.

SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;

Resultado:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fluffy    |
| Meow      |
| Scratch   |
+-----------+
(6 rows affected)

Todas las consultas deben devolver el mismo número de columnas

Cuando usas UNION cláusula, cada consulta debe tener el mismo número de columnas y deben estar en el mismo orden.

Si no, recibirá un error.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;

Resultado:

Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

Ese es el error que devuelve SQL Server cuando se usa un número desigual de columnas. Este error en particular indica que la misma restricción también se aplica a INTERSECT y EXCEPT operadores. El mensaje de error que reciba puede ser diferente, dependiendo de su DBMS.

Los tipos de datos deben ser compatibles

Además de requerir el mismo número de columnas, esas columnas deben tener un tipo de datos compatible.

No es necesario que sean del mismo tipo de datos, pero deberán ser compatibles. Es decir, deben ser compatibles mediante conversión implícita. Si los tipos de datos no coinciden, el DBMS debe poder realizar una conversión implícita para que coincidan.

Si no, recibirá un error.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;

Resultado:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Meow' to data type int.

Ordenar los resultados

Si desea ordenar los resultados con ORDER BY cláusula, deberá ponerlo en la última consulta. No puedes poner un ORDER BY separado cláusula en cada consulta, o para el caso, cualquier consulta que no sea la última.

Este es el error que recibo al intentar hacer eso en SQL Server:

SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;

Resultado:

Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'UNION'.

Por lo tanto, si queremos ordenar los resultados, necesitaremos hacer algo como esto:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;

Aplicando UNION a Más de dos Consultas

Los ejemplos anteriores combinaron los resultados de dos consultas diferentes, pero no hay nada que le impida agregar más. Puede usarlo para combinar los resultados de muchas consultas si es necesario.

Por ejemplo, si también tuviéramos un Birds tabla, podríamos hacer esto:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;

Normalización

Los ejemplos de esta página colocan a los gatos y los perros en dos tablas separadas. La razón por la que hice esto es porque es una forma clara y concisa de ilustrar cómo UNION funciona.

En la práctica, puede tener estos en la misma tabla llamados, por ejemplo, Pets , luego tenga un PetTypes separado mesa (o similar). Esto se conoce como normalización y es la forma en que se suelen diseñar las bases de datos relacionales.

Luego podría ejecutar una combinación en estas tablas para devolver los datos según sea necesario.