Quelle est la différence entre INet ANYopé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 INet ANYopé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", INni ANYun "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 à = ANYprendre 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 ANYconstruction prend un tableau (doit être un type de tableau réel), tandis que la deuxième variante de INprend 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é avecinANY est plus polyvalentLa ANYconstruction 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 idtrouve dans le tableau donné":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversion: « Trouver les lignes où idest 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 NULLne transmettent aucune de ces expressions. Pour inclure des NULLvaleurs 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.
ANYpeut ê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.)
NULLvaleurs? Cela WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;fonctionnerait-il aussi bien?
(id = ...) IS NOT TRUEfonctionne car id = ...évalue uniquement TRUEs'il y a une correspondance réelle. Résultats FALSEou NULLpasser 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' INopé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 ANYcela ne fonctionne pas avec les listes.