sql >> Base de Datos >  >> RDS >> MariaDB

Explicación del operador EXCEPT de MariaDB

En MariaDB, el EXCEPT El operador devuelve filas de la consulta de entrada de la izquierda que no son generadas por la consulta de entrada de la derecha.

Otra forma de decirlo es que devuelve todas las filas desde la izquierda SELECT conjunto de resultados excepto filas que están a la derecha SELECT conjunto de resultados.

Sintaxis

La sintaxis oficial es así:

SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

Lo anterior también incluye el INTERSECT y UNION operadores en la sintaxis, ya que la misma sintaxis se aplica a esos operadores.

A partir de MariaDB 10.4.0, se pueden usar paréntesis para especificar la precedencia.

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 usar el EXCEPT operador para devolver profesores que no son también estudiantes:

SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Entonces solo obtenemos valores que aparecen en Teachers que no aparecen en la tabla Students mesa.

De forma predeterminada, devuelve filas distintas, por lo que solo se devuelve una fila para Cathy , a pesar de que hay dos profesores con ese nombre. Podemos cambiar este comportamiento; más sobre esto más adelante.

También podemos cambiarlo y poner los Students mesa a la izquierda y Teachers a la derecha.

SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;

Resultado:

+-------------+
| StudentName |
+-------------+
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Es posible obtener el mismo resultado sin usar EXCEPT operador. Por ejemplo, podríamos reescribir nuestro primer ejemplo así:

SELECT 
    DISTINCT TeacherName
FROM Teachers t 
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);

Resultado:

+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Eso sí, el EXCEPT operador ayuda a simplificar el código de manera significativa.

Incluir duplicados

Por defecto, el EXCEPT operador aplica implícitamente un DISTINCT operación. En otras palabras, devuelve solo valores distintos de forma predeterminada.

Antes de MariaDB 10.5.0, el DISTINCT implícito era nuestra única opción:no pudimos especificar ALL . Sin embargo, MariaDB 10.5.0 introdujo el EXCEPT ALL y EXCEPT DISTINCT sintaxis.

Esto significa que ahora podemos hacer consultas como esta:

SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Cathy       |
| Ben         |
| Cathy       |
| Bill        |
+-------------+

Esta vez obtuvimos cuatro filas, en lugar de las dos que obtuvimos en nuestro primer ejemplo.

Podemos ver que ambos Cathys fueron devueltos en lugar de solo uno como en nuestro primer ejemplo.

¿En cuanto a Bill? Hay dos proyectos de ley en los Teachers table, pero aquí solo se devuelve uno. Probablemente se deba a que hay un proyecto de ley en Students tabla, lo que excluiría uno de los proyectos de ley de nuestros resultados.

Y aquí hay un ejemplo que usa explícitamente DISTINCT operador:

SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;

Resultado:

+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Como era de esperar, obtenemos el mismo resultado que obtendríamos si elimináramos DISTINCT operador.

En MariaDB 10.6.1, MINUS se introdujo como sinónimo de EXCEPT . Por lo tanto, podemos usar MINUS en lugar de EXCEPT en MariaDB 10.6.1 y posteriores.