Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Fonctionnement EXCEPT dans SQL Server

Vous pouvez utiliser le T-SQL EXCEPT opérateur dans SQL Server pour renvoyer des lignes distinctes de la requête d'entrée de gauche qui ne sont pas générées par la requête d'entrée de droite.

Syntaxe

La syntaxe ressemble à ceci :

{ <query_specification> | ( <query_expression> ) }   
{ EXCEPT }  
{ <query_specification> | ( <query_expression> ) }

En fait, la documentation Microsoft inclut le INTERSECT opérateur dans sa définition, car la même syntaxe s'applique à EXCEPT et INTERSECT .

La syntaxe Microsoft ressemble à ceci :

{ <query_specification> | ( <query_expression> ) }   
{ EXCEPT | INTERSECT }  
{ <query_specification> | ( <query_expression> ) }

Exemple

Imaginez que vous avez deux tables; Cats et Dogs .

Cats

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

Dogs

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

Nous pouvons utiliser le EXCEPT pour renvoyer uniquement les lignes distinctes de la requête d'entrée de gauche qui ne sont pas générées par la requête d'entrée de droite.

Voici un exemple.

SELECT CatName FROM Cats
EXCEPT
SELECT DogName FROM Dogs;

Résultat :

+-----------+
| CatName   |
|-----------|
| Flutter   |
| Scarcat   |
+-----------+

Nous n'obtenons donc que les valeurs qui apparaissent dans les Cats table qui n'apparaissent pas aussi dans le Dogs table. Comme mentionné, il renvoie des lignes distinctes, donc une seule ligne est renvoyée pour Flutter .

Nous pouvons également l'inverser et mettre les Dogs table à gauche et Cats à droite.

SELECT DogName FROM Dogs
EXCEPT
SELECT CatName FROM Cats;

Résultat :

+-----------+
| DogName   |
|-----------|
| Woofer    |
| Yelp      |
+-----------+

Le EXCEPT l'opérateur apparaît comme un LEFT ANTI SEMI JOIN dans le plan d'exécution.

Donc, notre premier exemple est similaire à ce qui suit :

SELECT 
    DISTINCT CatName
FROM Cats c 
WHERE NOT EXISTS (SELECT DogName FROM Dogs d
WHERE c.CatName = d.DogName);

Résultat :

+-----------+
| CatName   |
|-----------|
| Flutter   |
| Scarcat   |
+-----------+

Notez que lors de l'utilisation de EXCEPT , le nombre et l'ordre des colonnes doivent être les mêmes dans toutes les requêtes. De plus, les types de données doivent être compatibles. Ils ne doivent pas nécessairement être identiques, mais ils doivent être comparables par conversion implicite.

Aussi, lors de la comparaison des valeurs de colonne pour déterminer DISTINCT lignes, deux NULL les valeurs sont considérées comme égales.

Si vous avez l'intention d'utiliser EXCEPT dans les requêtes distribuées, notez qu'il n'est exécuté que sur le serveur local et non poussé vers le serveur lié, et cela pourrait donc affecter les performances.