IN
DSQL, PSQL, ESQL.
<value> [NOT] IN (<select_stmt> | <value_list>) <value_list> ::= <value_1> [, <value_2> ...]
Le prédicat IN
vérifie si la valeur de l’expression à gauche est présente dans l’ensemble des valeurs spécifiées à droite.L’ensemble des valeurs ne peut pas dépasser 1500 éléments.Le prédicat IN
peut être réécrit sous la forme équivalente suivante :
(<value> = <value_1> [OR <value> = <value_2> ...])
Lorsque vous utilisez le prédicat IN
dans les termes de recherche des requêtes DML, l’optimiseur de Firebird peut utiliser un index sur la colonne recherchée s’il est défini.
Dans la deuxième forme, le prédicat IN
vérifie si la valeur de l’expression de gauche est présente (ou absente, lorsqu’on utilise NOT IN
) dans le résultat de la sous-requête de droite.Le résultat de la sous-requête ne peut contenir qu’une seule colonne, sinon une erreur sera émise.“count of column list and variable list do not match”.
Les requêtes utilisant le prédicat IN
avec une sous-requête peuvent être réécrites en une requête similaire utilisant le prédicat EXISTS
.Par exemple, la requête suivante :
SELECT
model, speed, hd
FROM PC
WHERE
model IN (SELECT model
FROM product
WHERE maker = 'A');
Vous pouvez réécrire une requête similaire en utilisant un prédicat. EXISTS
:
SELECT
model, speed, hd
FROM PC
WHERE
EXISTS (SELECT *
FROM product
WHERE maker = 'A'
AND product.model = PC.model);
Cependant, une requête utilisant NOT IN
ne donnera pas toujours le même résultat qu’une requête NOT EXISTS
.La raison en est que le prédicat EXISTS
renvoie toujours TRUE
ou FALSE
, alors que le prédicat IN
peut renvoyer NULL
dans les cas suivants :
-
Lorsque la valeur à vérifier est
NULL
et que la liste dansIN
n’est pas vide. -
Lorsque la valeur à vérifier n’est pas une correspondance dans la liste
IN
et que l’une des valeurs estNULL
.
Dans ces deux cas, le prédicat IN
renverra NULL
, tandis que le prédicat EXISTS
correspondant renverra FALSE
.Dans les conditions de recherche ou l’opérateur IF
, les deux résultats indiquent `Fail' et sont traités de la même manière.
Cependant, sur les mêmes données, NOT IN
retournera NULL
, alors que EXISTS
retournera TRUE
, ce qui provoquera le résultat inverse.
C’est ce que montre l’exemple suivant.
Supposons que vous ayez une requête comme celle-ci :
-- Je cherche des gens qui ne sont pas nés le même jour que...
-- Des habitants célèbres de New York
SELECT P1.name AS NAME
FROM Personnel P1
WHERE P1.birthday NOT IN (SELECT C1.birthday
FROM Celebrities C1
WHERE C1.birthcity = 'New York');
On peut supposer qu’une requête utilisant un prédicat produira un résultat similaire NOT EXISTS
:
-- Je cherche des gens qui ne sont pas nés le même jour que...
-- des habitants célèbres de New York
SELECT P1.name AS NAME
FROM Personnel P1
WHERE NOT EXISTS (SELECT *
FROM Celebrities C1
WHERE C1.birthcity = 'New York'
AND C1.birthday = P1.birthday);
Supposons qu’il n’y ait qu’un seul résident connu à New York et que sa date de naissance soit inconnue.Lorsque vous utilisez le prédicat EXISTS
, la sous-requête qu’il contient ne produira pas de résultats car la comparaison des dates de naissance à NULL
donnera UNKNOWN
.Ainsi, le résultat du prédicat NOT EXISTS
sera vrai pour chaque ligne de la requête principale.Alors que le résultat du prédicat NOT IN
sera UNKNOWN
et aucune ligne ne sera affichée.
IN
Trouver des employés avec des noms “Pete”, “Ann” et “Roger”:
SELECT *
FROM EMPLOYEE
WHERE FIRST_NAME IN ('Pete', 'Ann', 'Roger');
IN
Trouvez tous les ordinateurs pour lesquels il existe des modèles dont le fabricant commence par la lettre “A”:
SELECT
model, speed, hd
FROM PC
WHERE
model IN (SELECT model
FROM product
WHERE maker STARTING WITH 'A');