Opérateurs de comparaison modifiés par ANY, SOME ou ALL

Les opérateurs de comparaison qui introduisent une sous-requête peuvent être modifiés par les mots clés ALL ou ANY. SOME est un équivalent de ANY dans la norme ISO.

Les sous-requêtes introduites par un opérateur de comparaison modifié retournent une liste contenant aucune ou plusieurs valeurs et peuvent contenir une clause GROUP BY ou HAVING. Ces sous-requêtes peuvent être reformulées à l'aide de EXISTS.

En prenant comme exemple l'opérateur de comparaison >, >ALL signifie supérieur à toutes les valeurs. En d'autres termes, cela signifie supérieur à la valeur maximale. Par exemple, >> (1, 2, 3) signifie supérieur à 3. >ANY signifie supérieur à une valeur au moins, autrement dit supérieur à la valeur minimale. Donc >ANY (1, 2, 3) signifie supérieur à 1.

Pour qu'une ligne d'une sous-requête comportant >ALL réponde au critère défini dans la requête externe, la valeur de la colonne introduisant la sous-requête doit être supérieure à chaque valeur de la liste de valeurs retournée par la sous-requête.

De même, >ANY signifie qu'afin qu'une ligne satisfasse au critère défini dans la requête externe, la valeur spécifiée dans la colonne qui introduit la sous-requête doit être supérieure à au moins une valeur de la liste retournée par la sous-requête.

La requête suivante donne un exemple de sous-requête introduite par un opérateur de comparaison modifié par ANY. Elle recherche les produits dont les tarifs sont supérieurs ou égaux au tarif maximal de n'importe quelle sous-catégorie de produits.

USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE ListPrice >= ANY
    (SELECT MAX (ListPrice)
     FROM Production.Product
     GROUP BY ProductSubcategoryID)

Pour chaque sous-catégorie Product, la requête interne recherche le tarif maximal. Parmi toutes ces valeurs, la requête externe recherche les tarifs de produit particulier supérieurs ou égaux au tarif maximal de n'importe quelle sous-catégorie de produits. Si ANY est remplacé par ALL, la requête ne retourne que les produits dont le tarif est supérieur ou égal à tous les tarifs retournés dans la requête interne.

Si la sous-requête ne retourne aucune valeur, la requête entière ne retourne aucune valeur non plus.

L'opérateur =ANY est équivalent à IN. Par exemple, pour trouver les noms de tous les produits à roue fabriqués par Adventure Works Cycles, vous pouvez utiliser IN ou =ANY.

--Using =ANY
USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID =ANY
    (SELECT ProductSubcategoryID
     FROM Production.ProductSubcategory
     WHERE Name = 'Wheels')

--Using IN
USE AdventureWorks;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN
    (SELECT ProductSubcategoryID
     FROM Production.ProductSubcategory
     WHERE Name = 'Wheels')

Voici l'ensemble de résultats pour ces deux requêtes :

Name
--------------------------------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel

(14 row(s) affected)

Cependant, l'opérateur < >ANY diffère de NOT IN : < >ANY signifie not = a, ou not = b, ou not = c. NOT IN signifie not = a, et not = b, et not = c. <>ALL signifie la même chose que NOT IN.

Par exemple, la requête suivante recherche les clients situés dans un secteur non couvert par un vendeur.

Use AdventureWorks;
GO
SELECT CustomerID
FROM Sales.Customer
WHERE TerritoryID <> ANY
    (SELECT TerritoryID
     FROM Sales.SalesPerson)

Les résultats comprennent tous les clients, à l'exception de ceux dont le secteur géographique a pour valeur NULL, car chaque secteur affecté à un client est couvert par un vendeur. La requête interne recherche tous les secteurs géographiques couverts par les vendeurs puis, pour chaque secteur, la requête externe recherche les clients qui ne se trouvent dans aucun secteur.

Pour la même raison, lorsque vous utilisez NOT IN dans cette requête, les résultats ne comprennent aucun des clients.

Vous pouvez obtenir les mêmes résultats avec l'opérateur < >ALL, qui est l'équivalent de NOT IN.