Подтвердить что ты не робот

Проверьте, является ли композитное поле Postgres нулевым/пустым

С композитными типами 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, если какой-либо элемент в составном поле не является нулевым... а не когда ВСЕ из них не являются нулевыми. Есть ли способ обойти это, кроме проверки каждого поля?

4b9b3361

Ответ 1

IS NULL и IS NOT NULL тоже работают для сложных типов, поэтому эти два должны быть подходящими:

select * from bla where recipient is not null
select * from bla where recipient is null

Ответ 2

Чтобы уловить случаи, когда не все поля значения составные (строка/запись) имеют значение NULL:

SELECT *
FROM   bla
WHERE  NOT (recipient IS NULL);

<row-type> is NULL возвращает только TRUE, если все поля NULL.
<row-type> is NOT NULL возвращает только TRUE, если все поля NOT NULL.

Скобки необязательны. В любом случае приоритет оператора работает в нашу пользу.

Тестирование строки/записи для 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

SQL Fiddle.

по теме: