En MariaDB, el MINUS
El operador devuelve filas distintas de la consulta de entrada de la izquierda que no son generadas por la consulta de entrada de la derecha.
El MINUS
El operador se introdujo en MariaDB 10.6.1 como sinónimo de EXCEPT
operador a efectos de compatibilidad con Oracle. Por lo tanto, podemos usar MINUS
y EXCEPT
indistintamente (en MariaDB 10.6.1 y versiones posteriores).
Sin embargo, he descubierto que MINUS
el operador solo funciona cuando mi sql_mode = "oracle"
. Aunque esto no se menciona explícitamente en la documentación de MariaDB, está implícito en la tarea de implementar MINUS
operador en MariaDB.
Datos de muestra
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 MINUS
operador para devolver profesores que no son también estudiantes.
Establecer sql_mode
a Oracle
Antes de comenzar a usar MINUS
operador, establezcamos nuestro sql_mode
a oracle
:
SET sql_mode = "oracle";
Bien, ahora podemos continuar y usar MINUS
operador.
Ejemplo de MINUS
SELECT TeacherName FROM Teachers
MINUS
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
MINUS
SELECT TeacherName FROM Teachers;
Resultado:
+-------------+ | StudentName | +-------------+ | Faye | | Jet | | Spike | | Ein | +-------------+
Es posible obtener el mismo resultado sin usar MINUS
(o 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 | +-------------+
Incluir duplicados
De forma predeterminada, MINUS
operador aplica implícitamente un DISTINCT
operación. En otras palabras, devuelve solo valores distintos de forma predeterminada. Pero podemos especificar MINUS ALL
para incluir duplicados en el resultado:
SELECT TeacherName FROM Teachers
MINUS 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
MINUS 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.
¿No está en modo Oracle?
Esto es lo que sucede cuando intentamos usar MINUS
cuando no está en modo Oracle.
Restablezcamos nuestro sql_mode
a la configuración predeterminada:
SET sql_mode = default;
Ahora intentemos usar MINUS
operador de nuevo:
SELECT TeacherName FROM Teachers
MINUS
SELECT StudentName FROM Students;
Resultado:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT StudentName FROM Students' at line 3