Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como EXCEPT funciona no SQL Server


Você pode usar o T-SQL EXCEPT operador no SQL Server para retornar linhas distintas da consulta de entrada esquerda que não são geradas pela consulta de entrada direita.

Sintaxe


A sintaxe fica assim:
{ <query_specification> | ( <query_expression> ) }   
{ EXCEPT }  
{ <query_specification> | ( <query_expression> ) }

Na verdade, a documentação da Microsoft inclui o INTERSECT operador em sua definição, pois a mesma sintaxe se aplica a EXCEPT e INTERSECT .

A sintaxe da Microsoft é assim:
{ <query_specification> | ( <query_expression> ) }   
{ EXCEPT | INTERSECT }  
{ <query_specification> | ( <query_expression> ) }

Exemplo


Imagine que você tenha duas tabelas; Cats e Dogs .

Cats
+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Brush     |
| 2       | Scarcat   |
| 3       | Flutter   |
| 4       | Flutter   |
+---------+-----------+

Dogs
+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Yelp      |
| 2       | Woofer    |
| 3       | Brush     |
| 4       | Brush     |
+---------+-----------+

Podemos usar o EXCEPT operador para retornar apenas as linhas distintas da consulta de entrada esquerda que não são geradas pela consulta de entrada direita.

Aqui está um exemplo.
SELECT CatName FROM Cats
EXCEPT
SELECT DogName FROM Dogs;

Resultado:
+-----------+
| CatName   |
|-----------|
| Flutter   |
| Scarcat   |
+-----------+

Portanto, só obtemos valores que aparecem no Cats tabela que também não aparece em Dogs tabela. Como mencionado, ele retorna linhas distintas, portanto, apenas uma linha é retornada para Flutter .

Também podemos alternar e colocar o Dogs mesa à esquerda e Cats a direita.
SELECT DogName FROM Dogs
EXCEPT
SELECT CatName FROM Cats;

Resultado:
+-----------+
| DogName   |
|-----------|
| Woofer    |
| Yelp      |
+-----------+

O EXCEPT operador aparece como um LEFT ANTI SEMI JOIN no plano de execução.

Portanto, nosso primeiro exemplo é semelhante a fazer o seguinte:
SELECT 
    DISTINCT CatName
FROM Cats c 
WHERE NOT EXISTS (SELECT DogName FROM Dogs d
WHERE c.CatName = d.DogName);

Resultado:
+-----------+
| CatName   |
|-----------|
| Flutter   |
| Scarcat   |
+-----------+

Observe que ao usar EXCEPT , o número e a ordem das colunas devem ser iguais em todas as consultas. Além disso, os tipos de dados devem ser compatíveis. Na verdade, eles não precisam ser iguais, mas devem ser comparáveis ​​por meio de conversão implícita.

Além disso, ao comparar valores de coluna para determinar DISTINCT linhas, duas NULL os valores são considerados iguais.

Se você pretende usar EXCEPT em consultas distribuídas, observe que ele é executado apenas no servidor local e não enviado por push para o servidor vinculado e, portanto, isso pode afetar o desempenho.