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

Operador MariaDB MINUS explicado

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