9.17. Comparaisons de lignes et de tableaux
Cette section décrit des constructions adaptées aux comparaisons
entre groupes de valeurs. Ces formes sont syntaxiquement liées aux
formes des sous-requêtes de la section précédente, mais elles
n'impliquent pas de sous-requêtes. Les formes qui impliquent 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
...
Si l'expression du côté gauche renvoie NULL, ou s'il n'y a pas de
valeurs du côté droit égales et qu'au moins une expression du côté
droit renvoie NULL, le résultat de la construction IN est 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 le résultat de l'expression du côté
gauche est différent de toutes les expressions du côté droit. C'est
une notation raccourcie de
expression <> valeur1
AND
expression <> valeur2
AND
...
Si l'expression du côté gauche renvoie NULL, ou s'il existe des
valeurs différentes du côté droit et qu'au moins une expression du
côté droit renvoie NULL, le résultat de la construction
NOT IN est NULL et non pas vrai. Ceci
est en accord avec les règles du standard du SQL pour les
combinaisons booléennes de valeurs NULL.
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 surprendre le novice avec
NOT IN qu'avec IN. Quand cela est possible, il est préférable
d'exprimer la condition de façon positive.
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é, 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é (ce qui inclut le cas spécial
du tableau qui ne contient aucun élément).
Si l'expression de tableau ramène un tableau NULL, le résultat de
ANY est NULL. Si l'expression du côté
gauche retourne NULL, le résultat de ANY
est habituellement NULL (bien qu'un opérateur de comparaison non
strict puisse conduire à 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 est NULL, et non pas faux (« false ») (là aussi avec l'hypothèse d'un
opérateur de comparaison strict). Ceci est en accord avec les
règles du standard SQL pour les combinaisons booléennes de valeurs
NULL.
SOME est un synonyme de 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 à l'aide de
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 (ce qui inclut le cas spécial du tableau qui 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 est NULL. Si l'expression du côté
gauche retourne NULL, le résultat de ALL
est habituellement NULL (bien qu'un opérateur de comparaison non
strict puisse conduire à un résultat différent). De plus, si le
tableau du côté droit contient des éléments NULL et qu'aucune
comparaison false n'est obtenue, le résultat de ALL est NULL, et non pas true (là aussi avec
l'hypothèse d'un opérateur de comparaison strict). Ceci est en
accord avec les règles du standard SQL pour les combinaisons
booléennes de valeurs NULL.
9.17.5. Comparaison de lignes entières
constructeur_ligne opérateur constructeur_ligne
Chaque côté est un constructeur de lignes, tel que décrit dans la
Section 4.2.11,
« Constructeurs de lignes ». Les deux valeurs de
lignes doivent avoir le même nombre de lignes. Chaque côté est
évalué. Ils sont alors comparés sur toute la ligne. Les
comparaisons de lignes sont autorisées quand l'
opérateur
est =, <>, <, <=, >, >=, ou a une
sémantique similaire à l'un d'eux. (Pour être précis, un opérateur
peut être un opérateur de comparaison de ligne s'il est membre
d'une classe d'opérateurs B-Tree ou est le négateur du membre
= d'une classe d'opérateurs B-Tree.)
Les cas = et <> fonctionnent légèrement différemment des
autres. Les lignes sont considérées égales si leurs membres
correspondants sont non-nuls et égaux ; les lignes sont différentes
si des membres correspondants sont non-nuls et différents ;
autrement, 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 dès qu'une paire d'éléments
différents ou NULL est découverte. Si un des éléments de cette
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étermine 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
Avant PostgreSQL™ 8.2,
les cas <, <=, > et
>= n'étaient pas gérés d'après les
spécifications SQL. Une comparaison comme ROW(a,b) < ROW(c,d) était codée sous la forme
a < c AND b < d alors que le bon
comportement est équivalent à a < c OR
(a = c AND b < d).
constructeur_ligne IS DISTINCT FROM constructeur_ligne
Cette construction est similaire à une comparaison de ligne
<>, mais elle ne conduit pas à un
résultat NULL pour des entrées NULL. Au lieu de cela, une valeur
NULL est considérée différente (distincte) d'une valeur non-NULL et
deux valeurs NULL sont considérées égales (non distinctes). Du
coup, le résultat est toujours soit true soit false, jamais NULL.
constructeur_ligne IS NOT DISTINCT FROM constructeur_ligne
Cette construction est similaire à une comparaison de lignes
=, mais elle ne conduit pas à un résultat
NULL pour des entrées NULL. Au lieu de cela, une valeur NULL est
considérée différente (distincte) d'une valeur non NULL et deux
valeurs NULL sont considérées identiques (non distinctes). Du coup,
le résultat est toujours soit true soit false, jamais NULL.