Coalesce и Case-Когда с To_Date не работает должным образом (ошибка Postgres?)

Я использую Postgres 9.1. Следующий запрос не работает должным образом. Coalesce должен вернуть первое ненулевое значение. Однако этот запрос возвращает ноль (1?) Вместо даты (2).

select COALESCE(
    TO_DATE('','yyyymmdd'), --(1)
    TO_DATE('20130201','yyyymmdd') --(2)
    );

--(1) this evaluates independently to null
--(2) this evaluates independently to the date,
--    and therefore is the first non-null value

Что я делаю неправильно? Любое решение?

Редактировать: Это может не иметь ничего общего с Coalesce вообще. Я попробовал несколько экспериментов с конструкциями Case When; Оказывается, у Postgres есть этот большой уродливый баг, где он лечит TO_DATE('','yyyymmdd') как не нуль, даже если его выбор возвращает ноль.

[PS: Вычеркните выше, чтобы не вводить в заблуждение. В Postgres нет ошибки, но он не обрабатывает пустые строки как ноль. Смотрите ответ.]

1 ответ

Решение
SELECT TO_DATE('','yyyymmdd');

не оценивает NULL так как вы передаете пустую строку вместо NULL в качестве аргумента TO_DATE()

Это будет успешно оценено как NULL

SELECT TO_DATE(NULL,'yyyymmdd');

Если вы ожидаете пустую строку и хотите рассматривать ее как NULL ты можешь использовать NULLIF()

SELECT TO_DATE(NULLIF(dt, ''),'yyyymmdd')
  FROM 
(
  SELECT CAST('' AS VARCHAR(32)) dt
) q

Это значит, что ваш пример кода, который оценивает (1) как NULL

SELECT COALESCE(
    TO_DATE(NULLIF('', ''),'yyyymmdd'),       --(1)
    TO_DATE(NULLIF('20130201',''),'yyyymmdd') --(2)
);

и возвращается

| КОАЛЕСС |
-----------------------------------
| 01 февраля 2013 00:00:00+0000 |

Вот демоверсия SQLFiddle

Другие вопросы по тегам