Hay dos variantes de IN
expresiones:
expression IN (subquery)
expression IN (value [, ...])
Del mismo modo, dos variantes con ANY
construir:
expression operator ANY (subquery)
expression operator ANY (array expression)
Una subconsulta funciona para cualquier técnica, pero para el segundo forma de cada uno, IN
espera una lista de valores (como se define en SQL estándar) while = ANY
espera una matriz .
¿Cuál usar?
ANY
es una adición posterior y más versátil, se puede combinar con cualquier operador binario que devuelva un valor booleano. IN
se reduce a un caso especial de ANY
. De hecho, su segunda forma se reescribe internamente:
IN
se reescribe con = ANY
NOT IN
se reescribe con <> ALL
Compruebe el EXPLAIN
salida para cualquier consulta para ver por ti mismo. Esto prueba dos cosas:
IN
nunca puede ser más rápido que= ANY
.= ANY
no va a ser sustancialmente más rápido.
La elección debe decidirse por qué es más fácil de proporcionar :una lista de valores o una matriz (posiblemente como una matriz literal - un solo valor).
Si las identificaciones que va a pasar provienen de dentro de la base de datos de todos modos, es mucho más eficiente seleccionarlos directamente (subconsulta) o integrar la tabla de origen en la consulta con JOIN
(como comentó @mu).
Para pasar una lista larga de valores de su cliente y obtenga el mejor rendimiento , usa una matriz, unnest()
y únase, o proporciónelo como expresión de tabla usando VALUES
(como comentó @PinnyM). Pero tenga en cuenta que un JOIN
conserva posibles duplicados en la matriz / conjunto proporcionado mientras IN
o = ANY
no. Más:
- Optimización de una consulta de Postgres con un IN grande
En presencia de valores NULL, NOT IN
es a menudo la elección incorrecta y NOT EXISTS
sería correcto (y más rápido también):
- Seleccionar filas que no están presentes en otra tabla
Sintaxis para = ANY
Para la expresión de matriz, Postgres acepta:
- un constructor de matriz (la matriz se construye a partir de una lista de valores en el lado de Postgres) de la forma:
ARRAY[1,2,3]
- o una matriz literal de la forma
'{1,2,3}'
.
Para evitar conversiones de tipos no válidos, puede convertir explícitamente:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Relacionado:
- PostgreSQL:Problema al pasar la matriz al procedimiento
- Cómo pasar una matriz de tipo personalizada a la función de Postgres
O usted podría crear una función de Postgres tomando un VARIADIC
parámetro, que toma argumentos individuales y forma una matriz a partir de ellos:
- Pasar múltiples valores en un solo parámetro
¿Cómo pasar la matriz de Ruby?
Asumiendo id
ser integer
:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Pero solo estoy incursionando en Ruby. @mu proporciona instrucciones detalladas en esta respuesta relacionada:
- ¿Enviar una matriz de valores a una consulta sql en ruby?