MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Explicação do operador MariaDB MINUS


No MariaDB, o MINUS O operador retorna linhas distintas da consulta de entrada esquerda que não são geradas pela consulta de entrada direita.

O MINUS foi introduzido no MariaDB 10.6.1 como sinônimo de EXCEPT operador para fins de compatibilidade com Oracle. Portanto, podemos usar MINUS e EXCEPT alternadamente (no MariaDB 10.6.1 e posterior).

No entanto, descobri que o MINUS operador só funciona quando meu sql_mode = "oracle" . Embora isso não seja explicitamente mencionado na documentação do MariaDB, está implícito na tarefa de implementação do MINUS operador no MariaDB.

Dados de amostra


Suponha que temos as seguintes tabelas:
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 o MINUS operador para devolver professores que não são também alunos.

Definir sql_mode para Oracle


Antes de começarmos a usar o MINUS operador, vamos definir nosso sql_mode para oracle :
SET sql_mode = "oracle";

OK, agora podemos ir em frente e usar o MINUS operador.

Exemplo de MINUS

SELECT TeacherName FROM Teachers
MINUS
SELECT StudentName FROM Students;

Resultado:
+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Portanto, só obtemos valores que aparecem no Teachers tabela que também não aparece em Students tabela.

Por padrão, ele retorna linhas distintas, portanto, apenas uma linha é retornada para Cathy , embora existam dois professores com esse nome. Podemos mudar esse comportamento - mais sobre isso mais tarde.

Também podemos alternar e colocar o Students tabela à esquerda e Teachers a direita.
SELECT StudentName FROM Students
MINUS
SELECT TeacherName FROM Teachers;

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

É possível obter o mesmo resultado sem usar o MINUS (ou EXCEPT ) operador. Por exemplo, poderíamos reescrever nosso primeiro exemplo para isso:
SELECT 
    DISTINCT TeacherName
FROM Teachers t 
WHERE NOT EXISTS (SELECT StudentName FROM Students s
WHERE t.TeacherName = s.StudentName);

Resultado:
+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Incluir duplicatas


Por padrão, o MINUS operador aplica implicitamente um DISTINCT Operação. Em outras palavras, ele retorna apenas valores distintos por padrão. Mas podemos especificar MINUS ALL para incluir duplicatas no resultado:
SELECT TeacherName FROM Teachers
MINUS ALL
SELECT StudentName FROM Students;

Resultado:
+-------------+
| TeacherName |
+-------------+
| Cathy       |
| Ben         |
| Cathy       |
| Bill        |
+-------------+

Desta vez, obtivemos quatro linhas, em vez das duas que obtivemos em nosso primeiro exemplo.

Podemos ver que ambas as Cathys foram retornadas ao invés de apenas uma como no nosso primeiro exemplo.

Quanto a Bill? Existem duas contas em Teachers tabela, mas apenas um é retornado aqui. Provavelmente porque há um projeto de lei em Students tabela, o que excluiria uma das contas de nossos resultados.

E aqui está um exemplo que usa explicitamente o DISTINCT operador:
SELECT TeacherName FROM Teachers
MINUS DISTINCT
SELECT StudentName FROM Students;

Resultado:
+-------------+
| TeacherName |
+-------------+
| Ben         |
| Cathy       |
+-------------+

Como esperado, obtemos o mesmo resultado que obteríamos se removêssemos o DISTINCT operador.

Não está no Modo Oracle?


Veja o que acontece quando tentamos usar MINUS quando não estiver no modo Oracle.

Vamos redefinir nosso sql_mode para a configuração padrão:
SET sql_mode = default;

Agora vamos tentar usar o MINUS operador novamente:
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