Является Postgres способ объединения IS DISTINCT FROM
с ANY
или каким -либо другим аккуратным способом получить тот же результат?
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
Джек говорит, попробуйте topanswers.xyz
источник
источник
IS DISTINCT FROM
быть оператор? Похоже, просто техническое ограничение синтаксического анализатора, а не семантическая проблема.оператор
Это основано на умном операторе @ Дэниела .
Находясь в этом, создайте комбо функции / оператора, используя полиморфные типы . Тогда это работает для любого типа - так же, как конструкция.
И сделать функцию
IMMUTABLE
.Быстрый поиск по Symbolhound оказался пустым, поэтому оператор
<!>
, похоже, не используется ни в одном из модулей.Если вы собираетесь многократно использовать этот оператор, вы можете еще немного его уточнить, чтобы помочь планировщику запросов ( как, например, в примечании ). Для начала, вы можете добавить
COMMUTATOR
иNEGATOR
положение , чтобы помочь оптимизатору запросов. ЗаменитьCREATE OPERATOR
сверху на это:И добавить:
Но дополнительные пункты не помогут с вариантом использования под рукой, и простые индексы все равно не будут использоваться. Это гораздо сложнее, чтобы достичь этого. (Я не пробовал.) Подробности читайте в главе «Информация по оптимизации оператора» в руководстве.
Прецедент
Тестовый пример в вопросе может быть успешным, только если все значения в массиве идентичны. Для массива в question (
'{null,A}'::text[]
) результат всегда TRUE. Это предназначено? Я добавил еще один тест для "ОТЛИЧАЕТСЯ ОТ ВСЕХ":Альтернатива со стандартными операторами
можно почти перевести на
foo = ALL (test_arr)
дает ...TRUE
.. если все элементыfoo
FALSE
.. если любойNOT NULL
элемент есть<> foo
NULL
.. если хотя бы один элементIS NULL
и нет элемента<> foo
Таким образом, оставшийся угол случай , где
-
foo IS NULL
- и
test_arr
состоит из ничего , кромеNULL
элементов.Если любой из них может быть исключен, мы сделали. Поэтому используйте простой тест if
- столбец определен
NOT NULL
.- или вы знаете, что массив никогда не бывает пустым.
Остальное, тест дополнительно:
Где
'A'
и'B'
могут быть какие-то разные значения. Объяснение и альтернативы в этом связанном вопросе о SO:массив всех NULL в PostgreSQL
Опять же, если вы знаете о каком-либо значении, которое не может существовать
test_arr
, например, в пустой строке''
, вы все равно можете упростить:Вот полная тестовая матрица для проверки всех комбинаций:
Это немного более многословно, чем решение Андрея
EXCEPT
, но оно значительно быстрее.источник
OPERATOR
, должно ли бытьCOMMUTATOR
(иNEGATOR
, возможно, с обратнымIS NOT DISTINCT FROM
оператором) предложение? postgresql.org/docs/current/static/xoper-optimization.htmlapp_status <!> any(array[3,6])
. К сожалению, это не влияет на записи. Это работает с целыми числами?