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.