Возвращает ноль, если запись не найдена

У меня есть запрос внутри хранимой процедуры, которая суммирует некоторые значения внутри таблицы:

SELECT SUM(columnA) FROM my_table WHERE columnB = 1 INTO res;

После этого выбора я вычитаю значение res из целого числа, полученного другим запросом, и возвращаю результат. Если пункт WHERE проверен, все работает нормально. Но если это не так, все мои функции возвращают пустой столбец (возможно, потому, что я пытаюсь вычесть целое число с пустым значением).

Как сделать так, чтобы мой запрос возвращал ноль, если условие WHERE не выполняется?


person giozh    schedule 24.07.2013    source источник
comment
INTO var, добавленное к SELECT ..., допустимо только в коде PL/pgSQL, но не в обычном SQL. Я предполагаю, что это часть функции PL/pgSQL или оператора DO. Правильный?   -  person Erwin Brandstetter    schedule 24.07.2013


Ответы (3)


Ты мог бы:

SELECT COALESCE(SUM(columnA), 0) FROM my_table WHERE columnB = 1
INTO res;

Это работает, потому что ваш запрос имеет агрегатную функцию и, следовательно, всегда возвращает строку, даже если в базовой таблице ничего не найдено.

Обычные запросы без агрегирования в таком случае вернут нет строки. COALESCE никогда бы не позвонили и не смогли бы вас спасти. Имея дело с одним столбцом, мы можем вместо этого обернуть весь запрос:

SELECT COALESCE( (SELECT columnA FROM my_table WHERE ID = 1), 0)
INTO res;

Работает и для вашего исходного запроса:

SELECT COALESCE( (SELECT SUM(columnA) FROM my_table WHERE columnB = 1), 0)
INTO res;

Подробнее о COALESCE() в руководстве .
Подробнее о функциях агрегирования читайте в руководстве.
Дополнительные альтернативы в следующем посте:

person Erwin Brandstetter    schedule 24.07.2013
comment
@FreshPrinceOfSO: я думаю, следует отметить, что COALESCE — это стандарт SQL для этого. - person Erwin Brandstetter; 24.07.2013
comment
У меня был неудачный опыт с COALESCE... Скажем так, мы больше не друзья. - person Kermit; 24.07.2013
comment
@FreshPrinceOfSO Это больше I had a bad experience with SQL Server, чем I had a bad experience with COALESCE. Нет ничего плохого в COALESCE в других СУБД. - person Ihor Romanchenko; 24.07.2013

Я не знаком с postgresql, но в SQL Server или Oracle использование подзапроса будет работать, как показано ниже (в Oracle SELECT 0 будет SELECT 0 FROM DUAL)

SELECT SUM(sub.value)
FROM
( 
  SELECT SUM(columnA) as value FROM my_table
  WHERE columnB = 1
  UNION
  SELECT 0 as value
) sub

Может быть, это сработает и для postgresql?

person Jim    schedule 24.07.2013

Вы также можете попробовать: (я попробовал это, и это сработало для меня)

SELECT ISNULL((SELECT SUM(columnA) FROM my_table WHERE columnB = 1),0)) INTO res;
person Aamir Waheed    schedule 24.10.2013