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