Qual é a diferença entre IN
e ANY
operador no PostgreSQL?
O mecanismo de funcionamento de ambos parece ser o mesmo. Alguém pode explicar isso com um exemplo?
Qual é a diferença entre IN
e ANY
operador no PostgreSQL?
O mecanismo de funcionamento de ambos parece ser o mesmo. Alguém pode explicar isso com um exemplo?
Respostas:
(Nem IN
nem ANY
é um "operador". Uma "construção" ou "elemento de sintaxe".)
Logicamente , citando o manual :
IN
é equivalente a= ANY
.
Mas existem duas variantes de sintaxe de IN
e duas variantes de ANY
. Detalhes:
IN
pegar um conjunto é equivalente a = ANY
pegar um conjunto , conforme demonstrado aqui:
Mas a segunda variante de cada uma não é equivalente à outra. A segunda variante da ANY
construção leva um array (deve ser um tipo de array real), enquanto a segunda variante de IN
leva uma lista de valores separados por vírgulas . Isso leva a diferentes restrições na passagem de valores e também pode levar a diferentes planos de consulta em casos especiais:
=any()
mas usado comin
ANY
é mais versátilA ANY
construção é muito mais versátil, pois pode ser combinada 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 de escalas melhor para cada um:
Relacionado:
"Encontrar linhas onde id
está na matriz fornecida":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversão: "Encontrar linhas onde nãoid
está 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 de forma inequívoca. Caso contrário, um elenco explícito pode ser necessário, como '{1,2}'::int[]
.
As linhas com id IS NULL
não passam em nenhuma dessas expressões. Para incluir NULL
valores adicionais:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)
sempre resultará nas mesmas linhas que SELECT * from mytable where id = ANY('{1, 2, 3}')
, mesmo que possam ter planos de consulta diferentes.
ANY
não pode ser combinado com o !=
operador. Não acho que esteja documentado, mas select * from foo where id != ANY (ARRAY[1, 2])
não é o mesmo que select * from foo where id NOT IN (1, 2)
. Por outro lado, select * from foo where NOT (id = ANY (ARRAY[1, 2]))
funciona como esperado.
ANY
pode ser combinado com o !=
operador. Mas há mais do que isso. Eu adicionei um capítulo acima. (Observe que <>
é o operador no SQL padrão - embora também !=
seja aceito no Postgres.)
NULL
valores? Funcionaria WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
tão bem?
(id = ...) IS NOT TRUE
funciona porque id = ...
só avalia TRUE
se há uma correspondência real. Resultados FALSE
ou NULL
passar no nosso teste. Consulte: stackoverflow.com/a/23767625/939860 . Sua expressão adicionada testa para outra coisa. Isso seria equivalenteWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Existem dois pontos óbvios, bem como os pontos na outra resposta:
Eles são exatamente equivalentes ao usar subconsultas:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);
Por outro lado:
Apenas o IN
operador permite uma lista simples:
SELECT * FROM table
WHERE column IN(… , … , …);
Presumir que eles são exatamente os mesmos me surpreendeu várias vezes quando esqueci que ANY
não funciona com listas.