¿Cuál es la diferencia entre el operador INy ANYen PostgreSQL?
El mecanismo de trabajo de ambos parece ser el mismo. ¿Alguien puede explicar esto con un ejemplo?
¿Cuál es la diferencia entre el operador INy ANYen PostgreSQL?
El mecanismo de trabajo de ambos parece ser el mismo. ¿Alguien puede explicar esto con un ejemplo?
Respuestas:
(Ni INtampoco ANYes un "operador". Un "constructo" o "elemento de sintaxis").
Lógicamente , citando el manual :
INes equivalente a= ANY.
Pero hay dos variantes de sintaxisIN y dos variantes de ANY. Detalles:
IN tomar un conjunto es equivalente a = ANYtomar un conjunto , como se demuestra aquí:
Pero la segunda variante de cada uno no es equivalente a la otra. La segunda variante de la ANYconstrucción toma una matriz (debe ser un tipo de matriz real), mientras que la segunda variante de INtoma una lista de valores separados por comas . Esto conduce a diferentes restricciones al pasar valores y también puede conducir a diferentes planes de consulta en casos especiales:
=any()pero usado coninANY es más versátilLa ANYconstrucción es mucho más versátil, ya que se puede combinar con varios operadores, no solo =. Ejemplo:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
Para una gran cantidad de valores, proporcionar un conjunto de escalas mejor para cada uno:
Relacionado:
"Encuentra filas donde idestá en la matriz dada":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
Inversión: "Buscar filas donde noid está en la 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}'));
Los tres equivalentes. El primero con el constructor de matriz , los otros dos con literal de matriz . El tipo de datos puede derivarse del contexto sin ambigüedades. De lo contrario, es posible que se requiera un elenco explícito, como'{1,2}'::int[] .
Las filas con id IS NULLno pasan ninguna de estas expresiones. Para incluir NULLvalores adicionalmente:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)siempre dará como resultado las mismas filas que SELECT * from mytable where id = ANY('{1, 2, 3}'), incluso si potencialmente podrían tener diferentes planes de consulta.
ANY no se puede combinar con el !=operador. No creo que esté documentado, pero select * from foo where id != ANY (ARRAY[1, 2])no es lo mismo que select * from foo where id NOT IN (1, 2). Por otro lado, select * from foo where NOT (id = ANY (ARRAY[1, 2]))funciona como se esperaba.
ANYse puede combinar con el !=operador. Pero hay más. Agregué un capítulo arriba. (Tenga en cuenta que <>es el operador en SQL estándar, aunque también !=se acepta en Postgres.)
NULLvalores? ¿ WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;Funcionaría igual de bien?
(id = ...) IS NOT TRUEfunciona porque id = ...solo evalúa TRUEsi hay una coincidencia real. Resultados FALSEo NULLpasar nuestra prueba. Consulte: stackoverflow.com/a/23767625/939860 . Tus pruebas de expresión agregadas para otra cosa. Esto sería equivalenteWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
Hay dos puntos obvios, así como los puntos de la otra respuesta:
Son exactamente equivalentes cuando se utilizan subconsultas:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);Por otra parte:
Solo el INoperador permite una lista simple:
SELECT * FROM table
WHERE column IN(… , … , …);Suponer que son exactamente iguales me ha sorprendido varias veces al olvidar que ANYno funciona con listas.