¿Cuál es la diferencia entre el operador IN
y ANY
en 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 IN
y ANY
en PostgreSQL?
El mecanismo de trabajo de ambos parece ser el mismo. ¿Alguien puede explicar esto con un ejemplo?
Respuestas:
(Ni IN
tampoco ANY
es un "operador". Un "constructo" o "elemento de sintaxis").
Lógicamente , citando el manual :
IN
es equivalente a= ANY
.
Pero hay dos variantes de sintaxisIN
y dos variantes de ANY
. Detalles:
IN
tomar un conjunto es equivalente a = ANY
tomar un conjunto , como se demuestra aquí:
Pero la segunda variante de cada uno no es equivalente a la otra. La segunda variante de la ANY
construcción toma una matriz (debe ser un tipo de matriz real), mientras que la segunda variante de IN
toma 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 conin
ANY
es más versátilLa ANY
construcció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 id
está 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 NULL
no pasan ninguna de estas expresiones. Para incluir NULL
valores 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.
ANY
se 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.)
NULL
valores? ¿ WHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;
Funcionaría igual de bien?
(id = ...) IS NOT TRUE
funciona porque id = ...
solo evalúa TRUE
si hay una coincidencia real. Resultados FALSE
o NULL
pasar 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 IN
operador permite una lista simple:
SELECT * FROM table
WHERE column IN(… , … , …);
Suponer que son exactamente iguales me ha sorprendido varias veces al olvidar que ANY
no funciona con listas.