9.17. Comparaisons de lignes et de tableaux

Cette section décrit plusieurs constructions spécialisées pour les comparaisons multiples entre des groupes de valeurs. Ces formes sont syntaxiquement en relation avec les formes de sous-requêtes de la section précédente mais n'impliquent pas de sous-requêtes. Ces formes impliquant des sous-expressions de tableaux sont des extensions de PostgreSQL™ ; le reste est compatible avec SQL. Toutes les formes d'expression documentées dans cette section renvoient des résultats booléens (true/false).

9.17.1. IN

expression IN (valeur [, ...])

Le côté droit est une liste entre parenthèses d'expressions scalaires. Le résultat est vrai (« true ») si le côté gauche de l'expression est égal à une des expressions du côté droit. C'est une notation raccourcie de

expression = valeur1
OR
expression = valeur2
OR
...

Notez que si l'expression du côté gauche renvoie nul ou s'il n'y a pas de valeurs du côté droit égales et qu'au moins une des expressions du côté droit renvoie la valeur NULL, le résultat de la construction IN sera NULL et non pas faux. Ceci est en accord avec les règles du standard SQL pour les combinaisons booléennes de valeurs NULL.

9.17.2. NOT IN

expression NOT IN (valeur [, ...])

Le côté droit est une liste entre parenthèses d'expressions scalaires. Le résultat est vrai (« true ») si l'expression du côté gauche est différente de toutes les expressions du côté droit. Ceci est une notation raccourcie pour

expression <> valeur1
AND
expression <> valeur2
AND
...

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

[Astuce]

Astuce

x NOT IN y est équivalent à NOT (x IN y) dans tout les cas. Néanmoins, les valeurs NULL ont plus de chances de survenir pour le novice avec l'utilisation de NOT IN qu'en utilisant IN. Il est préférable d'exprimer votre condition de façon positive si possible.

9.17.3. ANY/SOME (array)

expression opérateur ANY (expression tableau)
expression opérateur SOME (expression tableau)

Le côté droit est une expression entre parenthèses qui doit renvoyer une valeur de type array. L'expression du côté gauche est évaluée et comparée à chaque élément du tableau en utilisant l'opérateur donné et qui doit renvoyer un résultat booléen. Le résultat de ANY est vrai (« true ») si un résultat vrai est obtenu. Le résultat est faux (« false ») si aucun résultat vrai n'est trouvé (ceci incluant le cas spécial où le tableau ne contient aucun élément).

Si l'expression de tableau ramène un tableau NULL, le résultat de ANY sera NULL. Si l'expression du côté gauche ramène un NULL, le résultat de ANY est habituellement NULL (bien qu'un opérateur de comparaison non strict pourrait ramener un résultat différent). De plus, si le tableau du côté droit contient des éléments NULL et qu'aucune comparaison vraie n'est obtenue, le résultat de ANY sera NULL, et non pas false (encore une fois, en supposant un opérateur de comparaison strict). Ceci est fait en accord avec les règles normales de SQL pour les combinaisons booléennes de valeurs NULL.

SOME est un synonyme pour ANY.

9.17.4. ALL (array)

expression opérateur ALL (expression tableau)

Le côté droit est une expression entre parenthèses qui doit renvoyer une valeur de type tableau. L'expression du côté gauche est évaluée et comparée à chaque élément du tableau en utilisant l'opérateur donné qui doit renvoyer un résultat booléen. Le résultat de ALL est vrai (« true ») si toutes les comparaisons renvoient vrai (ceci inclut le cas spécial où le tableau ne contient aucun élément). Le résultat est faux (« false ») si un résultat faux est trouvé.

Si l'expression de tableau ramène un tableau NULL, le résultat de ALL sera NULL. Si l'expression du côté gauche ramène un NULL, le résultat de ALL est habituellement NULL (bien qu'un opérateur de comparaison non strict pourrait ramener un résultat différent). De plus, si le tableau du côté droit contient des éléments NULL et qu'aucune comparaison true n'est obtenue, le résultat de ALL sera NULL, et non pas true (encore une fois, en supposant un opérateur de comparaison strict). Ceci est fait en accord avec les règles normales de SQL pour les combinaisons booléennes de valeurs NULL.

9.17.5. Comparaison sur des lignes complètes

constructeur_lignes IS DISTINCT FROM constructeur_lignes

Chaque côté est un constructeur de lignes comme décrit dans la Section 4.2.11, « Constructeurs de lignes ». Les deux valeurs de lignes doivent avoir le même nombre de lignes. Les comparaisons de lignes sont autorisées quand l'opérateur est =, <>, <, <=, > ou >=, ou a une sémantique similaire a un de ceux-ci. (Pour être spécifique, un opérateur peut être un opérateur de comparaison de ligne s'il est un membre d'une classe d'opérateur B-Tree ou est le négateur du membre = d'une classe d'opérateur B-Tree.)

Les cas = et <> fonctionnent légèrement différemment des autres. Les deux lignes sont considérées égales si leur membres correspondants sont non nul et égaux ; les lignes sont différentes si un des membres correspondants est non nul et différent ; sinon le résultat de la comparaison de ligne est inconnu (NULL).

Pour les cas <, <=, > et >=, les éléments de ligne sont comparés de gauche à droite. La comparaison s'arrête tant que des éléments différents ou NULL sont découverts. Si un des éléments d'une paire est NULL, le résultat de la comparaison de la ligne est inconnu, donc NULL ; sinon la comparaison de cette paire d'éléments déterminent le résultat. Par exemple, ROW(1,2,NULL) < ROW(1,3,0) est vrai, non NULL, car la troisième paire d'éléments n'est pas considérée.

[Note]

Note

Avant PostgreSQL™ 8.2, les cas <, <=, > et >= n'étaient pas gérés suivant la spécification SQL. Une comparaison comme ROW(a,b) < ROW(c,d) était implémentée comme a < c AND b < d alors que le bon comportement est équivalent à a < c OR (a = c AND b < d).

constructeur_lignes IS DISTINCT FROM constructeur_lignes

Cette construction est similaire à une comparaison de lignes <> mais cela ne ramène pas de NULL pour des entrées NULL. À la place, une valeur NULL est considérée différente (distincte) de toute valeur non NULL et deux valeurs NULL sont considérées égales (non distinctes). Du coup, le résultat sera toujours soit true soit false, jamais NULL.

constructeur_lignes IS NOT DISTINCT FROM constructeur_lignes

Cette construction est similaire à une comparaison = de lignes mais elle ne donne pas NULL pour des entrées NULL. À la place, toute valeur NULL est considérée comme différente d'une valeur non NULL alors que deux valeurs NULL sont considérées identiques. Du coup, le résultat sera toujours soit true soit false, mais jamais NULL.