Qual é a diferença entre INe ANYoperador 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 INe ANYoperador no PostgreSQL?
O mecanismo de funcionamento de ambos parece ser o mesmo. Alguém pode explicar isso com um exemplo?
Respostas:
(Nem INnem 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 INe duas variantes de ANY. Detalhes:
IN pegar um conjunto é equivalente a = ANYpegar um conjunto , conforme demonstrado aqui:
Mas a segunda variante de cada uma não é equivalente à outra. A segunda variante da ANYconstrução leva um array (deve ser um tipo de array real), enquanto a segunda variante de INleva 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 cominANY é mais versátilA ANYconstruçã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 idestá 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 NULLnão passam em nenhuma dessas expressões. Para incluir NULLvalores 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.
ANYpode 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.)
NULLvalores? Funcionaria WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;tão bem?
(id = ...) IS NOT TRUEfunciona porque id = ...só avalia TRUEse há uma correspondência real. Resultados FALSEou NULLpassar 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 INoperador 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 ANYnão funciona com listas.