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

Explication de l'opérateur SQL Server ALL

Dans SQL Server, le ALL L'opérateur peut être utilisé avec une sous-requête pour comparer une valeur scalaire avec un ensemble de valeurs à une seule colonne renvoyé par la sous-requête.

Il est également vrai que le SELECT clause et UNION l'opérateur accepte tous les deux un ALL argument, bien que cet usage ait un objectif différent (autorise les doublons dans le jeu de résultats).

Vous trouverez ci-dessous des exemples d'utilisation de ALL opérateur avec une sous-requête.

Exemple

Supposons que nous ayons deux tables ; Cats et Dogs

Cats

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
+---------+-----------+

Exécutons maintenant une sous-requête en utilisant ALL opérateur.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT DogName FROM Dogs);

Résultat :

(0 rows affected)

Dans ce cas, aucune ligne n'a été renvoyée. C'est parce que ALL nécessite que l'expression scalaire se compare positivement à chaque valeur renvoyée par la sous-requête.

Dans ce cas, la sous-requête était si large que toutes les lignes de Dogs le tableau a été rendu. Cela nécessiterait que chaque chien ait au moins un chat correspondant avec le même nom.

Modifions légèrement la sous-requête.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (
    SELECT DogName FROM Dogs 
    WHERE DogId = 2
    );

Résultat :

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 2       | Fluffy    |
+---------+-----------+

Dans ce cas, j'obtiens un résultat positif, car toutes les lignes renvoyées par la sous-requête avaient une ligne correspondante dans le Cats tableau (bien qu'une seule ligne).

Renvoyer l'opposé

Nous pouvons utiliser n'importe quel opérateur de comparaison avec ALL . Nous pourrions donc modifier les exemples précédents pour retourner le résultat opposé, simplement en changeant l'opérateur égal (=) à un opérateur différent de (soit <> ou la norme non ISO != ).

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName <> ALL (SELECT DogName FROM Dogs);

Résultat :

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 3       | Scratch   |
+---------+-----------+

Ainsi, au lieu de renvoyer toutes les lignes qui ont une ligne correspondante dans la sous-requête, nous renvoyons toutes les lignes qui n'en ont pas avoir une ligne correspondante.

Et nous pouvons faire la même chose avec l'autre exemple.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName <> ALL (
    SELECT DogName FROM Dogs 
    WHERE DogId = 2
    );

Résultat :

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 3       | Scratch   |
+---------+-----------+

Erreur 116 ?

Si vous obtenez l'erreur 116 lors de l'utilisation de ALL , c'est probablement parce que vous sélectionnez plusieurs colonnes dans votre sous-requête. Le ALL L'opérateur ne peut être utilisé qu'avec des sous-requêtes qui ont un ensemble de résultats d'une colonne.

Voici un exemple de la façon dont nous pouvons provoquer cette erreur.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT DogId, DogName FROM Dogs);

J'ai simplement ajouté une colonne à la sous-requête.

C'est une erreur courante lors de l'utilisation de l'opérateur générique pour sélectionner toutes les colonnes de la sous-requête.

SELECT 
    CatId,
    CatName
FROM Cats c 
WHERE c.CatName = ALL (SELECT * FROM Dogs);

Dans tous les cas, le résultat est le même :

Msg 116, Level 16, State 1, Line 5
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.