9.16. Expressions de sous-requêtes
Cette section décrit les expressions de sous-requêtes compatibles
SQL disponibles sous PostgreSQL™. Toutes les formes
d'expressions documentées dans cette section renvoient des résultats
booléens (true/false).
9.16.1. EXISTS
EXISTS ( sous-requête )
L'argument d'EXISTS est une instruction
SELECT
arbitraire ou
une sous-requête. La sous-requête est
évaluée pour déterminer si elle renvoie des lignes. Si elle en
renvoie au moins une, le résultat d'EXISTS est vrai (« true ») ; si elle n'en renvoie aucune, le
résultat d'EXISTS est faux
(« false »).
La sous-requête peut faire référence à des variables de la requête
englobante qui agiront comme des constantes à chaque évaluation de
la sous-requête.
La sous-requête n'est habituellement pas exécutée plus qu'il n'est
nécessaire pour déterminer si au moins une ligne est renvoyée. Elle
n'est donc pas forcément exécutée dans son intégralité. Il est de
ce fait fortement déconseillé d'écrire une sous-requête qui
présente des effets de bord (tels que l'appel de fonctions de
séquence) ; il est extrèmement difficile de prédire si celui-ci va
intervenir.
Puisque le résultat ne dépend que d'un éventuel retour de lignes,
et pas de leur contenu, la liste des champs retournés par la
sous-requête n'a normalement aucun intérêt. Une convention de
codage habituelle consiste à écrire tous les tests EXISTS sous la forme EXISTS(SELECT 1 WHERE ...). Il y a toutefois des
exceptions à cette règle, comme les sous-requêtes utilisant
INTERSECT.
L'exemple suivant, simpliste, ressemble à une jointure interne sur
col2 mais il sort au plus une ligne pour
chaque ligne de tab1, même s'il y a
plusieurs correspondances dans les lignes de tab2 :
SELECT col1 FROM tab1
WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
9.16.2. IN
expression IN (sous-requête)
Le côté droit est une sous-expression entre parenthèses qui ne peut
retourner qu'une seule colonne. L'expression de gauche est évaluée
et comparée à chaque ligne du résultat de la sous-requête. Le
résultat de IN est vrai
(« true ») si une ligne
équivalente de la sous-requête est trouvée. Le résultat est faux
(« false ») si aucune ligne
correspondante n'est trouvée (ce qui inclut le cas spécial de la
sous-requête ne retournant aucune ligne).
Si l'expression de gauche est NULL ou s'il n'existe pas de
correspondance avec les valeurs du côté droit et qu'au moins une
ligne du côté droit est NULL, le résultat de la construction
IN est NULL, et non faux. Ceci est en
accord avec les règles normales du SQL pour les combinaisons
booléennes de valeurs NULL.
Comme avec EXISTS, on ne peut pas
assumer que la sous-requête est évaluée complètement.
constructeur_ligne IN (sous-requête)
Le côté gauche de cette forme de IN est
un constructeur de ligne comme décrit dans la Section 4.2.11,
« Constructeurs de lignes ». Le côté droit est une
sous-requête entre parenthèses qui doit renvoyer exactement autant
de colonnes qu'il y a d'expressions dans le côté gauche. Les
expressions côté gauche sont évaluées et comparées ligne à ligne au
résultat de la sous-requête. Le résultat de IN est vrai (« true ») si une ligne équivalente de la
sous-requête est trouvée. Le résultat est faux (« false ») si aucune ligne correspondante n'est
trouvée (ce qui inclut le cas spécial de la sous-requête ne
retournant aucune ligne).
Comme d'habitude, les valeurs NULL dans les lignes sont combinées
suivant les règles habituelles des expressions booléennes SQL. Deux
lignes sont considérées égales si tous leurs membres correspondant
sont non nuls et égaux ; les lignes diffèrent si le contenu de
leurs membres sont non nuls et différents ; sinon le résultat de la
comparaison de la ligne est inconnu, donc nul. Si tous les
résultats par lignes sont différents ou nuls, avec au moins un
NULL, alors le résultat de IN est nul.
9.16.3. NOT IN
expression NOT IN (sous-requête)
Le côté droit est une sous-requête entre parenthèses, qui doit
retourner exactement une colonne. L'expression de gauche est évalué
et comparée à cauqe ligne de résultat de la sous-requête. Le
résultat de NOT IN n'est
« true » que si des lignes
différentes de la sous-requête sont trouvées (ce qui inclut le cas
spécial de la sous-requête ne retournant pas de ligne). Le résultat
est « false » si une ligne
égale est trouvée.
Si l'expression de gauche est nulle, ou qu'il n'y a pas de valeur
égale à droite et qu'au moins une ligne de droite est nulle, le
résultat du NOT IN est nul, pas vrai.
Cela concorde avec les règles normales du SQL pour les combinaisons
bouléennes de valeurs nulles.
Comme pour EXISTS, on ne peut assumer
que la sous-requête est évaluée dans son intégralité.
constructeur_ligne NOT IN (sous-requête)
Le côté gauche de cette forme de NOT IN
est un constructeur de lignes, comme décrit dans la Section 4.2.11,
« Constructeurs de lignes ». Le côté droit est une
sous-requête entre parenthèses qui doit renvoyer exactement autant
colonnes qu'il y a d'expressions dans la ligne de gauche. Les
expressions de gauche sont évaluées et comparée ligne à ligne au
résultat de la sous-requête. Le résultat de NOT
IN n'est vrai (« true ») que si seules des lignes différentes de
la sous-requête sont trouvées (ce qui inclut le cas spécial de la
sous-requête ne retournant aucune ligne). Le résultat est faux
(« false ») si une ligne égale
est trouvée.
Comme d'habitude, les valeurs nulles des lignes sont combinées en
accord avec les règles normales des expressions bouléennes SQL.
Deux lignes sont considérées égales si tous leurs membres
correspondant sont non-nuls et égaux ; les lignes sont différentes
si les membres correspondant sont non-nuls et différents ; dans
tous les autres cas, le résultat de cette comparaison de ligne est
inconnu (nul). Si tous les résultats par ligne sont différents ou
nuls, avec au minimum un nul, alors le résultat du NOT IN est nul.
9.16.4. ANY/SOME
expression opérateur ANY (sous-requête)
expression opérateur SOME (sous-requête)
Le côté droit est une sous-requête entre parenthèses qui ne doit
retourner qu'une seule colonne. L'expression du côté gauche est
évaluée et comparée à chaque ligne du résultat de la sous-requête à
l'aide de l'
opérateur
indiqué, ce qui doit aboutir à une résultat booléen. Le résultat de
ANY est vrai (« true ») si l'un des résultats est vrai. Le
résultat est faux (« false »)
si aucun résultat vrai n'est trouvé (ce qui inclut le cas spécial
de la requête ne retournant aucune ligne).
SOME est un synonyme de ANY. IN est équivalent à
= ANY.
En l'absence de succès, mais si au moins une ligne du côté droit
conduit à NULL avec l'opérateur, le résultat de la construction
ANY est nul et non faux. Ceci est en
accord avec les règles standard SQL pour les combinaisons booléenne
de valeurs NULL.
Comme pour EXISTS, on ne peut assumer
que la sous-requête est évaluée entièrement.
constructeur_ligne operator ANY (sous-requête)
constructeur_ligne operator SOME (sous-requête)
Le côté gauche de cette forme ANY est un
constructeur de ligne, tel que décrit dans la Section 4.2.11,
« Constructeurs de lignes ». Le côté droit est une
sous-requête entre parenthèses, qui doit renvoyer exactement autant
de colonnes qu'il y a d'expressions dans la ligne de gauche. Les
expressions du côté gauche sont évaluées et comparées ligne à ligne
au résultat de la sous-requête à l'aide de l'
opérateur
donné. Le résultat de
ANY est « true » si la comparaison renvoie true pour une
ligne quelconque de la sous-requête. Le résultat est
« false » si la comparaison
renvoie false pour chaque ligne de la sous-requête (ce qui inclut
le cas spécial de la sous-requête ne retournant aucune ligne). Le
résultat est NULL si la comparaison ne renvoie true pour aucune
ligne, et renvoie NULL pour au moins une ligne.
Voir Section 9.17.5,
« Comparaison de lignes entières » pour la
signification détaillée d'une comparaison ligne à ligne.
9.16.5. ALL
expression opérateur ALL
(sous-requête)
Le côté droit est une sous-requête entre parenthèses qui ne doit
renvoyer qu'une seule colonne. L'expression gauche est évaluée et
comparée à chaque ligne du résultat de la sous-requête à l'aide de
l'
opérateur
, ce qui doit
renvoyer un résultat booléen. Le résultat de ALL est vrai (« true ») si toutes les lignes renvoient true (ce
qui inclut le cas spécial de la sous-requête ne retournant aucune
ligne). Le résultat est faux (« false ») si un résultat faux est découvert. Le
résultat est NULL si la comparaison ne renvoie pas false pour
toutes les lignes, et si elle renvoie NULL pour au moins une ligne.
NOT IN est équivalent à <> ALL.
Comme pour EXISTS, on ne peut assumer
que la sous-requête est évaluée entièrement.
constructeur_ligne opérateur ALL (sous-requête)
Le côté gauche de cette forme de ALL est
un constructeur de lignes, tel que décrit dans la Section 4.2.11,
« Constructeurs de lignes ». Le côté droit est une
sous-requête entre parenthèses qui doit renvoyer exactement le même
nombre de colonnes qu'il y a d'expressions dans la ligne de gauche.
Les expressions du côté gauche sont évaluées et comparées ligne à
ligne au résultat de la sous-requête à l'aide de l'
opérateur
donné. Le résultat de
ALL est « true » si la comparaison renvoie true pour
toutes les lignes de la sous-requête (ce qui inclut le cas spécial
de la sous-requête ne retournant aucune ligne). Le résultat est
« false » si la comparaison
renvoie false pour une ligne quelconque de la sous-requête. Le
résultat est NULL si la comparaison ne renvoie false pour aucune
ligne de la sous-requête, et si elle renvoit NULL pour au moins une
ligne.
Voir Section 9.17.5,
« Comparaison de lignes entières » pour la
signification détaillée d'une comparaison ligne à ligne.
9.16.6. Comparaison de lignes
constructeur_ligne opérateur (sous-requête)
Le côté gauche est un constructeur de lignes, tel que décrit dans
la Section 4.2.11,
« Constructeurs de lignes ». Le côté droit est une
sous-requête entre parenthèses qui doit renvoyer exactement autant
de colonnes qu'il y a d'expressions du côté gauche. De plus, la
sous-requête ne peut pas renvoyer plus d'une ligne. (Si elle ne
renvoie aucune ligne, le résultat est considéré nul.) Le côté
gauche est évalué et comparé ligne complète avec la ligne de
résultat de la sous-requête.
Voir Section 9.17.5,
« Comparaison de lignes entières » pour plus de
détails sur la signification d'une comparaison ligne à ligne.