Es una manera de combinar postgres IS DISTINCT FROMcon ANYo alguna otra forma elegante de conseguir el mismo resultado?
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo <> any(array[null, 'A']);
count
-------
1
(1 row)
select count(*)
from (select 'A' foo union all select 'Z' union all select null) z
where foo is distinct from any(array[null, 'A']);
ERROR: syntax error at or near "any"
LINE 3: where foo is distinct from any(array[null, 'A']);
^
postgresql
null
postgresql-9.3
Jack dice que intente topanswers.xyz
fuente
fuente

IS DISTINCT FROMser un operador? Parece solo una limitación técnica del analizador en lugar de un problema semántico.Operador
Esto se basa en el operador inteligente de @Daniel .
Mientras lo hace, cree el combo de función / operador utilizando tipos polimórficos . Entonces funciona para cualquier tipo, al igual que la construcción.
Y hacer la función
IMMUTABLE.Una búsqueda rápida con Symbolhound quedó vacía, por lo que el operador
<!>no parece estar en uso en ninguno de los módulos.Si va a utilizar mucho este operador, puede desarrollarlo un poco más para ayudar al planificador de consultas ( como los sugeridos en un comentario ). Para empezar, puede agregar las cláusulas
COMMUTATORyNEGATORpara ayudar al optimizador de consultas. ReemplazarCREATE OPERATORdesde arriba con esto:Y añadir:
Pero las cláusulas adicionales no ayudarán con el caso de uso en cuestión y los índices simples todavía no se utilizarán. Es mucho más sofisticado lograr eso. (No lo he intentado). Lea el capítulo "Información de optimización del operador" en el manual para obtener más detalles.
Caso de prueba
El caso de prueba en la pregunta solo puede tener éxito si todos los valores de la matriz son idénticos. Para la matriz en la pregunta (
'{null,A}'::text[]) el resultado es siempre VERDADERO. ¿Es eso intencionado? Agregué otra prueba para "ES DISTINTO DE TODO":Alternativa con operadores estándar
puede casi ser traducido a
foo = ALL (test_arr)rinde ...TRUE.. si todos los elementos sonfooFALSE.. si algúnNOT NULLelemento es<> fooNULL.. si al menos un elementoIS NULLy ningún elemento es<> fooEntonces, el caso de la esquina restante es donde
-
foo IS NULL- y
test_arrconsiste en nada más queNULLelementos.Si cualquiera de los dos puede descartarse, ya hemos terminado. Por lo tanto, use la prueba simple if
- la columna está definida
NOT NULL.- o que sabe la matriz no es todos los valores NULL.
De lo contrario, prueba adicionalmente:
Donde
'A'y'B'puede ser cualquier valor distinto. Explicación y alternativas bajo esta pregunta relacionada sobre SO:¿Es la matriz todos NULL en PostgreSQL
Nuevamente, si conoce algún valor que no puede existir
test_arr, por ejemplo, la cadena vacía'', aún puede simplificar:Aquí hay una matriz de prueba completa para verificar todas las combinaciones:
Esto es un poco más detallado que la
EXCEPTsolución de Andriy , pero es sustancialmente más rápido.fuente
OPERATOR, caso de que elCOMMUTATOR(yNEGATOR, tal vez con la inversaIS NOT DISTINCT FROMdel operador) Cláusula suministrar? postgresql.org/docs/current/static/xoper-optimization.htmlapp_status <!> any(array[3,6]). Desafortunadamente, no tiene ningún efecto en los registros. ¿Funciona con enteros?