Estoy usando el tipo de matriz nativa de Postgres y trato de encontrar los registros donde la ID no está en las ID de destinatario de la matriz.
Puedo encontrar dónde están EN:
SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))
Pero esto no funciona:
SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3 = NOT ANY (recipient_ids))
¿Cuál es la forma correcta de evaluar esta afección?
arrays
postgresql
usuario577808
fuente
fuente
WHERE 3 NOT IN recipient_ids
el trabajo?text[]
yint[]
matriz:select not(array[1,2,3] @> array[3]);
null
columna está contenida o no en una matriz, siempre dirá que no. Me tomó como 20 minutos depurar varios métodos de contenido para llegar a la conclusión de que no se puede verificar si una matriz contiene un valor nuloRespuestas:
Siempre puedes negar
WHERE (condition)
conWHERE NOT (condition)
fuente
ANY
lugar de aIN
medida querecipient_ids
crece su lista de entrada: stackoverflow.com/questions/1009706/…Podría darle la vuelta un poco y decir "3 no es igual a todos los ID":
Del manual fino :
fuente
any
no funciona en este casoany
yall
en postgres doc, que dice: "x <> ANY (a,b,c)
es equivalente ax <> a OR <> b OR x <> c
". ref: postgresqltutorial.com/postgresql-any postgresqltutorial.com/postgresql-allAumento de las
ALL/ANY
respuestasPrefiero todas las soluciones que utilicen
all
oany
para lograr el resultado, apreciando las notas adicionales (por ejemplo, sobre NULL s). Como otra mejora, aquí hay una forma de pensar en esos operadores.Puede pensar en ellos como operadores de cortocircuito :
all(array)
recorre todos los valores de la matriz, comparando cada uno con el valor de referencia utilizando el operador proporcionado. Tan pronto como se obtiene una comparaciónfalse
, el proceso termina con falso, de lo contrario verdadero. (Comparable a la lógica de cortocircuitoand
).any(array)
recorre todos los valores de la matriz, comparándolos con el valor de referencia utilizando el operador proporcionado. Tan pronto como se obtiene una comparacióntrue
, el proceso termina con verdadero, de lo contrario falso. (Comparable a la lógica de cortocircuitoor
).Esta es la razón por la
3 <> any('{1,2,3}')
que no produce el resultado deseado: el proceso compara 3 con 1 para la desigualdad, que es verdadero, e inmediatamente devuelve verdadero. Un solo valor en la matriz diferente de 3 es suficiente para que toda la condición sea verdadera. El 3 en la última posición de la matriz es prob. nunca usado.3 <> all('{1,2,3}')
por otro lado, se asegura de que todos los valores no sean iguales 3. Se ejecutarán todas las comparaciones que arrojen verdadero hasta un elemento que arroje falso (el último en este caso), para devolver falso como resultado general. Esto es lo que quiere el OP.fuente
not (3 = any(recipient_ids))
?fuente
3 <> ANY(ARRAY[1,2,3,4])
. Debería haber funcionado de esa manera: \una actualización:
a partir de postgres 9.3,
también puede usarlo
NOT
en conjunto con el@>
operador (contiene) para lograr esto.ES DECIR.
SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids @> ARRAY[3];
fuente
Cuidado con los NULL
Ambos
ALL
:Y
ANY
:Funcionaría siempre que
some_array
no sea nulo. Si la matriz puede ser nula, debe contabilizarla con coalesce (), por ejemploO
De los documentos :
fuente
Tenga en cuenta que los operadores ANY / ALL no funcionarán con índices de matriz. Si se tienen en cuenta los índices:
y lo negativo:
Luego se puede crear un índice como:
fuente
&&
SELECT COUNT(*) FROM "messages" WHERE ARRAY[3] && recipient_ids
.