Ответ 1
IS NULL
и IS NOT NULL
тоже работают для сложных типов, поэтому эти два должны быть подходящими:
select * from bla where recipient is not null
select * from bla where recipient is null
С композитными типами postgres вы можете в основном построить поле со структурой, определяемой как другая таблица. У меня есть составное поле, называемое "получателем" типа "человек". Это поле получателя часто остается пустым в моем конкретном сценарии. Каков правильный способ проверить, пустое ли составное поле. Я пробовал:
select * from bla where recipient is not null
select * from bla where recipient is null
select * from bla where recipient = null
select * from bla where recipient != null
Во всех этих случаях он ничего не возвращает. Итак, как вы правильно проверяете, является ли составное значение пустым или нет?
UPDATE
После некоторого большего чтения, похоже, что это моя проблема:
Можно подумать, что
!(x IS NULL) = x IS NOT NULL
истинно во всех случаях. Но есть исключение - составные типы. Когда одно поле составного значенияNULL
, а другое полеNOT NULL
, результат обоих операторов равен false.IS NULL
истинно, только если все поляNULL
.IS NOT NULL
истинно, только если все поляNOT NULL
. Для любого случая между ними оба оператора возвращают false.
У меня есть некоторые поля, которые являются нулевыми, а другие - нет. Я надеялся, что поле будет считаться NOT NULL, если какой-либо элемент в составном поле не является нулевым... а не когда ВСЕ из них не являются нулевыми. Есть ли способ обойти это, кроме проверки каждого поля?
IS NULL
и IS NOT NULL
тоже работают для сложных типов, поэтому эти два должны быть подходящими:
select * from bla where recipient is not null
select * from bla where recipient is null
Чтобы уловить случаи, когда не все поля значения составные (строка/запись) имеют значение NULL:
SELECT *
FROM bla
WHERE NOT (recipient IS NULL);
<row-type> is NULL
возвращает только TRUE
, если все поля NULL
. <row-type> is NOT NULL
возвращает только TRUE
, если все поля NOT NULL
.
Скобки необязательны. В любом случае приоритет оператора работает в нашу пользу.
Демонстрация различных опций:
CREATE TEMP TABLE recipient (r text, i int); -- to register the row type
SELECT recipient
, recipient IS NULL AS all_null
, recipient IS NOT NULL AS all_notnull
, NOT recipient IS NULL AS some_notnull
, NOT recipient IS NOT NULL AS some_null
FROM (
VALUES
(('foo', 1 )::recipient)
, ((NULL , 2 )::recipient)
, ((NULL , NULL)::recipient)
) AS tbl(recipient);
Результат:
recipient | all_null | all_notnull | some_notnull | some_null
-----------+----------+-------------+--------------+-----------
(foo,1) | f | t | t | f
(,2) | f | f | t | t
(,) | t | f | f | t
по теме: