Quelle est la différence entre IN
et ANY
opérateur dans PostgreSQL?
Le mécanisme de travail des deux semble être le même. Quelqu'un peut-il expliquer cela avec un exemple?
Quelle est la différence entre IN
et ANY
opérateur dans PostgreSQL?
Le mécanisme de travail des deux semble être le même. Quelqu'un peut-il expliquer cela avec un exemple?
Réponses:
(Ni un "opérateur", IN
ni ANY
un "opérateur". Une "construction" ou un "élément de syntaxe".)
Logiquement , citant le manuel :
IN
équivaut à= ANY
.
Mais il existe deux variantes de syntaxeIN
et deux variantes de ANY
. Détails:
IN
prendre un ensemble équivaut à = ANY
prendre un ensemble , comme démontré ici:
Mais la deuxième variante de chacun n'est pas équivalente à l'autre. La deuxième variante de la ANY
construction prend un tableau (doit être un type de tableau réel), tandis que la deuxième variante de IN
prend une liste de valeurs séparées par des virgules . Cela conduit à différentes restrictions dans la transmission des valeurs et peut également conduire à différents plans de requête dans des cas particuliers:
=any()
mais utilisé avecin
ANY
est plus polyvalentLa ANY
construction est beaucoup plus polyvalente, car elle peut être combinée avec divers opérateurs, pas seulement =
. Exemple:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Pour un grand nombre de valeurs, fournir un ensemble de meilleures échelles pour chacune:
En relation:
"Rechercher les lignes où se id
trouve dans le tableau donné":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: « Trouver les lignes où id
est pas dans le tableau »:
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
Les trois équivalents. Le premier avec un constructeur de tableau , les deux autres avec un littéral de tableau . Le type de données peut être dérivé du contexte sans ambiguïté. Sinon, une distribution explicite peut être requise, comme '{1,2}'::int[]
.
Les lignes avec id IS NULL
ne transmettent aucune de ces expressions. Pour inclure des NULL
valeurs en plus:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
donnera toujours les mêmes lignes que SELECT * from mytable where id = ANY('{1, 2, 3}')
, même si elles peuvent potentiellement avoir des plans de requête différents.
ANY
ne peut pas être combiné avec l' !=
opérateur. Je ne pense pas que ce soit documenté, mais ce select * from foo where id != ANY (ARRAY[1, 2])
n'est pas la même chose que select * from foo where id NOT IN (1, 2)
. D'autre part, select * from foo where NOT (id = ANY (ARRAY[1, 2]))
fonctionne comme prévu.
ANY
peut être combiné avec l' !=
opérateur. Mais il y a plus que cela. J'ai ajouté un chapitre ci-dessus. (Notez que <>
c'est l'opérateur en SQL standard - bien qu'il !=
soit également accepté dans Postgres.)
NULL
valeurs? Cela WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
fonctionnerait-il aussi bien?
(id = ...) IS NOT TRUE
fonctionne car id = ...
évalue uniquement TRUE
s'il y a une correspondance réelle. Résultats FALSE
ou NULL
passer notre test. Voir: stackoverflow.com/a/23767625/939860 . Votre expression ajoutée teste autre chose. Ce serait équivalentWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Il y a deux points évidents, ainsi que les points de l'autre réponse:
Ils sont exactement équivalents lors de l'utilisation de sous-requêtes:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
D'autre part:
Seul l' IN
opérateur autorise une liste simple:
SELECT * FROM table
WHERE column IN(… , … , …);
Présumer qu'ils sont exactement les mêmes m'a surpris à plusieurs reprises lorsque j'ai oublié que ANY
cela ne fonctionne pas avec les listes.