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

9.23. Expressions de sous-requêtes

Cette section décrit les expressions de sous-requêtes, compatible SQL, et disponible dans PostgreSQL. Toutes les formes d'expression documentées dans cette section renvoient des résultats booléens (true/false).

9.23.1. EXISTS

EXISTS (subquery)

L'argument de EXISTS est une requête SELECT arbitraire ou une sous-requête. La sous-requête est évaluée pour déterminer si elle renvoie des lignes. Si elle renvoie au moins une ligne, le résultat de EXISTS est « true » ; si la sous-requête ne renvoie aucune ligne, le résultat de EXISTS est « false ».

La sous-requête peut faire référence à des variables provenant de la requête englobante, qui agira comme constantes lors de toute évaluation de la sous-requête.

La sous-requête s'exécutera seulement suffisamment longtemps pour déterminer qu'au moins une ligne sera renvoyée. Elle ne sera donc pas exécuté entièrement. Il est déconseillé d'écrire une sous-requête qui a des effets secondaires (tels qu'appeler des fonctions de séquence)  le fait que les effets secondaires surviennent n'est pas prévisible.

Comme le résultat dépend seulement du fait que des lignes sont renvoyées ou pas, et non pas sur le contenu de ces lignes, la liste en sortie de la sous-requête n'a pas d'importance. Une convention commune de codage est d'écrire tous les tests EXISTS sous la forme EXISTS(SELECT 1 WHERE ...). Il existe néanmoins des exceptions à cette règle, comme les sous-requêtes qui utilisent INTERSECT.

Cet exemple simple est comme une jointure interne sur col2, mais il produit au plus une ligne pour chaque ligne de tab1, même s'il existe plus lignes correspondantes dans tab2 :

SELECT col1
FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
 

9.23.2. IN

expression IN (subquery)

Le côté droit est une sous-requête entre parenthèses, qui doit renvoyer exactement une ligne. L'expression côté gauche est évaluée et comparée à chaque ligne du résultat de la sous-requête. Le résultat de IN vaut « true » si au moins une ligne identique est trouvée dans la sous-requête. Le résultat est « false » si aucune ligne identique n'a été trouvée (y compris dans le cas où la sous-requête ne renvoit aucune ligne).

Notez que si l'expression côté gauche renvoie NULL ou s'il y a aucune valeur identique côté droit et au moins une ligne renvoyant NULL côté droit, le résultat de la construction IN sera NULL, et non pas false. Ceci est en accord avec les règles normales du SQL pour les combinaisons booléennes de valeurs NULL.

Comme avec EXISTS, il est déconseillé de supposer que la sous-requête sera complètement évaluée.

row_constructor IN (subquery)

Le côté gauche de cette syntaxe de IN est un constructeur de ligne, comme décrit dans 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 côté gauche. Les expressions du côté gauche sont évaluées et comparées, ligne par ligne, à chaque ligne du résultat de la sous-requête. Le résultat de IN vaut « true » si au moins une ligne identique est trouvée dans la sous-requête. Le résultat est « false » si aucune ligne identique n'est trouvée (y compris le cas où la sous-requête ne renvoie aucune ligne).

Comme d'habitude, les valeurs NULL dans les lignes sont combinées par les règles habituelles des expressions SQL booléennes. Deux lignes sont considérées égales si tous leurs membres correspondance sont non NULL et égaux ; les lignes ne sont pas égales si au moins un membre correspondant est non NULL et différent ; sinon le résultat de cette comparaison de ligne est inconnue (NULL). Si tous les résultats ligne par ligne sont soit différents soit NULL, avec au moins un NULL, alors le résultat de IN est NULL.

9.23.3. NOT IN

expression NOT IN (subquery)

Le côté droit est une sous-requête entre parenthèses, qui doit renvoyer exactement une colonne. L'expression côté gauche est évaluée et comparée à chaque ligne du résultat de la sous-requête. Le résultat de NOT IN vaut « true » si seulement des lignes différentes sont trouvées dans la sous-requête (y compris dans le cas où la sous-requête ne renvoie pas de lignes). Le résultat vaut « false » si au moins une ligne identique est trouvée.

Notez que si l'expression côté gauche renvoie NULL ou s'il n'existe pas de valeurs identiques côté droit et qu'au moins une ligne côté droit renvoie NULL, le résultat de la construction NOT IN sera NULL, et non pas true. Ceci est en accord avec les règles standards du SQL pour les combinaisons booléennes de valeurs NULL.

Tout comme EXISTS, il est déconseillé de supposer que la sous-requête sera totalement évaluée.

row_constructor NOT IN (subquery)

Le côté gauche de cette syntaxe pour NOT IN est un constructeur de lignes, comme décrit dans 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. Les expressions du côté gauche sont évaluées et comparées ligne par ligne pour chaque ligne du résultat de la sous-requête. Le résultat de NOT IN vaut « true » si seules des lignes différentes sont trouvées dans la sous-requête (y compris dans le cas où la sous-requête ne renvoie aucune ligne). Le résultat vaut « false » si aucune ligne identique n'est trouvée.

Comme d'habitude, les valeurs NULL dans les lignes sont combinées d'après les règles standards en SQL pour les expressions booléennes. Deux lignes sont considérées identiques si tous leurs membres correspondant sont non NULL et égaux ; les lignes sont différentes si au moins un membre correspondant est non NULL et différent ; sinon le résultat de cette comparaison de lignes est inconnu (NULL). Si tous les résultats ligne par ligne sont soit différentes soit NULL, avec au moins un NULL, alors le résultat de NOT IN is NULL.

9.23.4. ANY/SOME

expression operator ANY (subquery)
expression operator SOME (subquery)

Le côté droit est une sous-requête entre parenthèses, qui doit renvoyer exactement une colonne. L'expression côté gauche est évaluée et comparée à chaque ligne du résultat de la sous-requête en utilisant l'opérateur operator indiquée, qui doit renvoyer un résultat booléen. Le résultat de ANY vaut « true » si au moins une valeur true est obtenue dans le résultat. Le résultat vaut « false » si aucun résultat true n'est trouvé (y compris dans le cas où la sous-requête ne renvoie aucune ligne).

SOME est un synonyme pour ANY. IN est équivalent à = ANY.

Notez qe s'il n'y a pas de succès et qu'au moins une ligne côté droit renvoie NULL comme résultat de l'opérateur, le résultat de la construction ANY sera NULL, et non pas false. Ceci est en accord avec les règles SQL habituelles sur les combinaisons booléennes de valeurs NULL.

Comme avec EXISTS, il est déconseillé de supposer que la sous-requête sera totalement évaluée.

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

Le côté gauche de cette syntaxe de ANY est un constructeur de lignes, comme décrit dans Section 4.2.13. Le côté droit est une sous-requête entre parenthèses, qui doit renvoyer autant de colonnes qu'il y a d'expressions sur la ligne côté gauche. Les expressions côté gauche sont évaluées et comparées ligne par ligne pour chaque ligne du résultat de la sous-requête, en utilisant l'opérateur operator indiqué. Le résultat de ANY vaut « true » si la comparaison renvoie true pour au moins une ligne de la sous-requête. Le résultat vaut « false » si la comparaison renvoie false pour chaque ligne de la sous-requête (y compris dans le cas où la sous-requête ne renvoie aucune ligne). Le résultat est NULL si aucune comparaison avec une ligne de la sous-requête ne renvoie true, et qu'au mpoins une comparaison renvoie NULL.

Voir Section 9.24.5 pour les détails sur la signification de la comparaison d'un constructeur de ligne.

9.23.5. ALL

expression operator ALL (subquery)

Le côté droit est une sous-requête entre parenthèses, qui doit renvoyer exactement une colonne. L'expression côté gauche est évaluée, et comparée à chaque ligne du résultat de la sous-requête en utilisant l'opérateur operator indiqué, qui doit renvoyer un résultat booléen. Le résultat de ALL vaut « true » si toutes les lignes renvoient true (y compris dans le cas où la sous-requête ne renvoie aucune ligne). Le résultat vaut « false » si un résultat false est trouvé. Le résultat est NULL si aucune comparaison avec une ligne de la sous-requête renvoie false et au moins une comparaison renvoie NULL.

NOT IN est équivalent à <> ALL.

Comme avec EXISTS, il est déconseillé de supposer que la sous-requête sera totalement évaluée.

row_constructor operator ALL (subquery)

Le côté gauche de cette forme de ALL est un constructeur de lignes, comme décrit dans 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 côté gauche. Les expressions côté gauche sont évaluées et comparées ligne par ligne à chaque ligne du résultat de la sous-requête, en utilisant l'opérateur operator donné. Le résultat de ALL vaut « true » si la comparaison renvoie true pour toutes les lignes de la sous-requête (y compris le cas où la sous-requête ne renvoie aucune ligne). Le résultat est « false » si la comparaison renvoie false pour une ligne de la sous-requête. Le résultat est NULL si aucune comparaison avec une ligne de la sous-requête renvoie false et au moins une comparaison renvoie NULL.

Voir Section 9.24.5 pour les détails sur la signification d'une comparaison de constructeur de ligne.

9.23.6. Comparaison de ligne simple

row_constructor operator (subquery)

Le côté gauche est un constructeur de lignes, comme décrit dans 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 côté gauche. De plus, la sous-requête ne peut pas renvoyer plus d'une ligne. (Si elle renvoie zéro ligne, le résultat est pris pour NULL.) Le côté gauche est évalué et comparé ligne par ligne à la ligne seule du résultat de la sous-requête.

Voir Section 9.24.5 pour plus de détails sur la signification d'une comparaison de constructeur de lignes.