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.