No PostgreSQL, o
EXCEPT
O operador retorna linhas que são retornadas pela consulta de entrada esquerda que não são retornadas pela consulta de entrada direita. Isso também pode ser chamado de diferença entre duas consultas. Sintaxe
A sintaxe fica assim:
query1 EXCEPT [ALL] query2
As duplicatas são eliminadas a menos que
EXCEPT ALL
é usado. Exemplo
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
EXCEPT
operador para devolver professores que não são também alunos:SELECT TeacherName FROM Teachers
EXCEPT
SELECT StudentName FROM Students;
Resultado:
teachername ------------- Cathy Ben
Portanto, só obtemos valores que aparecem no
Teachers
tabela que também não aparece em Students
tabela. Por padrão, o
EXCEPT
operador retorna linhas distintas. Portanto, em nosso exemplo, apenas uma linha é retornada para Cathy
, embora existam dois professores com esse nome. O exemplo acima é o equivalente da seguinte consulta:
SELECT TeacherName FROM Teachers
EXCEPT DISTINCT
SELECT StudentName FROM Students;
Resultado:
teachername ------------- Cathy Ben
Este é o mesmo resultado que obtivemos quando não havia
DISTINCT
explícito palavra-chave. Podemos incluir duplicatas com o ALL
palavra-chave (mais sobre isso mais tarde). Podemos obter resultados diferentes, dependendo de qual tabela está à esquerda e qual está à direita. Aqui está um exemplo que coloca o
Students
tabela à esquerda e Teachers
a direita:SELECT StudentName FROM Students
EXCEPT
SELECT TeacherName FROM Teachers;
Resultado:
studentname ------------- Faye Jet Spike Ein
Desta vez, temos alunos que também não são professores.
Incluir duplicatas
Por padrão, o
EXCEPT
operador aplica implicitamente um DISTINCT
Operação. Em outras palavras, ele retorna apenas valores distintos por padrão. Podemos incluir o
ALL
palavra-chave para incluir duplicatas em nosso resultado:SELECT TeacherName FROM Teachers
EXCEPT ALL
SELECT StudentName FROM Students;
Resultado:
teachername ------------- Cathy Cathy Bill Ben
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. Uma alternativa
É possível obter o mesmo resultado sem usar o
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 ------------- Cathy Ben