sql >> Base de Datos >  >> RDS >> Mysql

Cláusula UNION de MySQL

En MySQL, la UNION La cláusula combina los resultados de varias consultas en un único conjunto de resultados.

Ejemplo

Supongamos que tenemos las siguientes tablas:

SELECT * FROM Teachers;
SELECT * FROM Students;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
+-----------+-------------+

+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
|         6 | Bill        |
+-----------+-------------+

Podemos insertar el UNION cláusula entre esos dos SELECT declaraciones para devolver a todos los profesores y estudiantes:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Los nombres de las columnas se toman del primer SELECT declaración.

De forma predeterminada, UNION cláusula aplica implícitamente un DISTINCT operación. En otras palabras, devuelve solo valores distintos de forma predeterminada. Entonces, los resultados anteriores contienen solo uno de Warren, Cathy y Bill. Esto es a pesar del hecho de que las tablas combinadas en realidad contienen dos Warren, dos Cathy y tres Bill (hay dos maestros llamados Cathy, un maestro y un cliente llamado Warren, y dos llamados Bill, así como un estudiante llamado Bill).

Aquí hay un ejemplo que usa explícitamente DISTINCT cláusula:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Entonces obtenemos el mismo resultado que obtuvimos sin DISTINCT cláusula.

Incluir duplicados

Podemos usar el ALL palabra clave para incluir valores duplicados en los resultados:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Cathy       |
| Bill        |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
| Warren      |
| Bill        |
+-------------+

Esta vez obtuvimos doce filas en lugar de las ocho que obtuvimos en nuestro primer ejemplo.

Podemos ver que ambos Cathys fueron devueltos y los tres Bills fueron devueltos.

TABLE Declaraciones

Desde MySQL 8.0.19 podemos usar UNION cláusula con la TABLE declaración.

He aquí un ejemplo:

TABLE Teachers
UNION
TABLE Students;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Ese es el equivalente de la siguiente consulta:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Notará que estas declaraciones devuelven más filas que en nuestro primer ejemplo anterior. Esto se debe a que estamos seleccionando todas las columnas de la tabla, lo que da como resultado que no haya duplicados donde antes había un duplicado. Por ejemplo, aquí se devuelven dos profesores llamados Bill, mientras que en el ejemplo anterior solo se devolvía uno. Eso es porque el TeacherId las columnas contienen valores diferentes, por lo que las filas no están duplicadas.

Usando ORDER BY Cláusula en consultas de unión

Podemos usar el ORDER BY cláusula en cada SELECT declaración y/o en la UNION combinada consulta.

En cada SELECT Declaración

Cuando usamos el ORDER BY cláusula en el SELECT individual declaraciones dentro de un UNION consulta, necesitamos incluir cada SELECT declaración entre paréntesis:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         4 | Ein         |
+-----------+-------------+

Tenga en cuenta que cuando hacemos esto, en realidad no ordena los resultados para la salida. Solo ordena los resultados con el fin de determinar el subconjunto de las filas seleccionadas para recuperar al aplicar el LIMIT cláusula.

Por lo tanto, usando ORDER BY sin el LIMIT cláusula no tiene efecto en la salida.

En conjunto UNION Consulta

También podemos usar un ORDER BY cláusula en toda la consulta, de modo que toda la salida se ordene en conjunto.

En este ejemplo, tomamos el ejemplo anterior y ordenamos los resultados combinados:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         4 | Ein         |
|         5 | Bill        |
|         6 | Bill        |
|         2 | Ben         |
+-----------+-------------+

Incluso cuando no se utiliza el ORDER BY cláusula dentro de cada SELECT declaración, cada SELECT declaración aún debe estar entre paréntesis, y el ORDER BY cláusula (o cualquier LIMIT cláusula) debe ir después de la última.

(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Eso sí, omitir los paréntesis produce el mismo resultado que el que tiene paréntesis:

SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;

Resultado:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Tenga en cuenta que si una columna que se ordenará usa un alias, esa columna debe ser referenciada por su alias (no por el nombre de la columna).

Ejemplo:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;

Resultado:

+--------+
| t      |
+--------+
| Ben    |
| Bill   |
| Cathy  |
| Ein    |
| Faye   |
| Jet    |
| Spike  |
| Warren |
+--------+

Esto es lo que sucede si no usamos el alias:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;

Resultado:

ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'

Número de columnas

El número de columnas devueltas por cada SELECT declaración debe ser la misma. Por lo tanto, no podemos hacer lo siguiente:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;

Resultado:

ERROR 1222 (21000): The used SELECT statements have a different number of columns

Tipos de datos

Columnas seleccionadas enumeradas en las posiciones correspondientes de cada SELECT declaración debe tener el mismo tipo de datos. Sin embargo, si no lo hacen, los tipos y longitudes de las columnas en UNION resultado tenga en cuenta los valores recuperados por todos los SELECT declaraciones.

Esto es lo que sucede si intentamos combinar el TeacherName columna con el StudentId columna:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| 1           |
| 2           |
| 3           |
| 4           |
| 5           |
| 6           |
+-------------+

Algunos otros RDBMS producirían un error en este caso, pero MySQL logra generar resultados sin errores.