PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 12.18 » Langage SQL » Fonctions et opérateurs » Expressions de sous-requêtes

9.22. 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.22.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 agissent 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 (telle que l'appel de fonctions de séquence) ; il est extrêmement difficile de prédire si ceux-ci se produisent.

Puisque le résultat ne dépend que d'un éventuel retour de lignes, et pas de leur contenu, la liste des colonnes retournées 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.22.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 soit é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.13. 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 comme égales si tous leurs membres correspondant sont non nuls et égaux ; les lignes diffèrent si le contenu de leurs membres est non nul et différent ; 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.22.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ée et comparée à chaque 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 booléennes de valeurs nulles.

Comme pour EXISTS, on ne peut assumer que la sous-requête soit é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.13. 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 de gauche sont évaluées et comparées 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 booléennes SQL. Deux lignes sont considérées comme égales si tous leurs membres correspondants sont non nuls et égaux ; les lignes sont différentes si les membres correspondants 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.22.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 à un 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éennes de valeurs NULL.

Comme pour EXISTS, on ne peut assumer que la sous-requête soit é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.13. 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 aucune comparaison avec une ligne de la sous-requête ne renvoie true et qu'au moins une comparaison renvoie NULL.

Voir Section 9.23.5 pour la signification détaillée d'une comparaison de constructeur de ligne.

9.22.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 aucune comparaison avec une ligne de la sous-requête ne renvoie false et qu'au moins une comparaison renvoie NULL.

NOT IN est équivalent à <> ALL.

Comme pour EXISTS, on ne peut assumer que la sous-requête soit é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.13. 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 colonne 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 aucune comparaison avec une ligne de la sous-requête ne renvoie false et qu'au moins une comparaison renvoie NULL.

Voir Section 9.23.5 pour la signification détaillée d'une comparaison de constructeur de ligne.

9.22.6. Comparaison de lignes seules

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.13. 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é comme 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.23.5 pour plus de détails sur la signification d'une comparaison de constructeur de ligne.