PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

IN vs ANY operador no PostgreSQL


(Nem IN nem ANY é um "operador". Um "construto" ou "elemento de sintaxe".)

Logicamente , citando o manual:

IN é equivalente a = ANY .

Mas há duas variantes de sintaxe de IN e duas variantes de ANY . Detalhes:
  • Como usar ANY em vez de IN em uma cláusula WHERE com Rails?

IN pegar um conjunto é equivalente a = ANY pegando um conjunto , como demonstrado aqui:
  • postgreSQL - em vs qualquer

Mas a segunda variante de cada uma não é equivalente à outra. A segunda variante do ANY construção recebe uma matriz (deve ser um tipo de array real), enquanto a segunda variante de IN pega uma lista de valores separada por vírgulas . Isso leva a diferentes restrições na passagem de valores e pode também levam a diferentes planos de consulta em casos especiais:
  • Índice não usado com =any() mas usado com in
  • Passe vários conjuntos ou matrizes de valores para uma função
  • Como combinar elementos em uma matriz de tipo composto?

ANY é mais versátil


O ANY construct é muito mais versátil, pois pode ser combinado com vários operadores, não apenas = . Exemplo:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');

Para um grande número de valores, fornecer um conjunto escala melhor para cada um:
  • Otimizando uma consulta Postgres com um grande IN

Relacionado:
  • O PostgreSQL pode indexar colunas de array?

Inversão / oposto / exclusão


"Encontre linhas onde id está na matriz fornecida":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);

Inversão:"Encontre linhas onde id é não na matriz":
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}'));

Todos os três equivalentes. O primeiro com construtor de array, os outros dois com literal de array. O tipo de dados pode ser derivado do contexto sem ambiguidade. Caso contrário, uma conversão explícita pode ser necessária, como '{1,2}'::int[] .

Linhas com id IS NULL não passe nenhuma dessas expressões. Para incluir NULL valores adicionalmente:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;