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

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

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

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

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

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

4b9b3361

Ответ 1

Вы можете:

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() в руководстве.
Подробнее о агрегированных функциях в руководстве.
Дополнительные альтернативы в этом более позднем сообщении:

Ответ 2

Я не знаком с 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?

Ответ 3

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

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