PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Opérateur IN vs ANY dans PostgreSQL

(Ni IN ni ANY est un "opérateur". Une "construction" ou un "élément de syntaxe".)

Logiquement , citant le manuel :

IN est équivalent à = ANY .

Mais il existe deux variantes de syntaxe de IN et deux variantes de ANY . Détails :

  • Comment utiliser ANY au lieu de IN dans une clause WHERE avec Rails ?

IN prendre un ensemble est équivalent à = ANY prendre un ensemble , comme démontré ici :

  • postgreSQL - dans vs n'importe lequel

Mais la deuxième variante de chacun n'est pas équivalente à l'autre. La deuxième variante du ANY la construction prend un tableau (doit être un type de tableau réel), tandis que la seconde variante de IN prend une liste de valeurs séparées par des virgules . Cela conduit à différentes restrictions dans le passage des valeurs et peut conduisent également à différents plans de requête dans des cas particuliers :

  • Index non utilisé avec =any() mais utilisé avec in
  • Transmettre plusieurs ensembles ou tableaux de valeurs à une fonction
  • Comment faire correspondre des éléments dans un tableau de type composite ?

ANY est plus polyvalent

Le ANY construct est beaucoup plus polyvalent, car il peut être combiné avec divers opérateurs, pas seulement = . Exemple :

SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

Pour un grand nombre de valeurs, fournir un ensemble s'adapte mieux pour chacun :

  • Optimiser une requête Postgres avec un grand IN

Connexe :

  • Est-ce que PostgreSQL peut indexer les colonnes d'un tableau ?

Inversion / contraire / exclusion

"Rechercher les lignes où id est dans le tableau donné":

SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

Inversion :"Rechercher les lignes où id n'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, un cast explicite peut être requis, comme '{1,2}'::int[] .

Lignes avec id IS NULL ne transmettez aucune de ces expressions. Pour inclure NULL valeurs supplémentaires :

SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;