2013-07-16 2 views
25

Я хотел бы выполнить деление в предложении SELECT. Когда я присоединяюсь к некоторым таблицам и использую агрегированную функцию, у меня часто есть нулевые или нулевые значения в качестве разделителей. На данный момент я только придумал этот способ избежать деления на нулевые и нулевые значения.Избегайте деления на ноль в PostgreSQL

(CASE(COALESCE(COUNT(column_name),1)) WHEN 0 THEN 1 
ELSE (COALESCE(COUNT(column_name),1)) END) 

Интересно, есть ли лучший способ сделать это?

+4

Отдел по нулевому значению не является проблемой в том, что деление на ноль. Кстати, count() никогда не возвращает null. –

+0

Я этого не знал! Спасибо за информацию. – William

ответ

24

С count() никогда не возвращается NULL (в отличие от других агрегатных функций), у вас есть только поймать 0 случай (который является единственным проблематичной случай так или иначе):

CASE count(column_name) 
    WHEN 0 THEN 1 
    ELSE count(column_name) 
END 

Quoting the manual about aggregate functions:

Следует отметить, что за count исключением, эти функции возвращают нулевое значение , если ни одна строка не выбрана.

+0

спасибо за ссылку, я не знал об этом +1 :) – Akash

92

Вы можете использовать функцию NULLIF, например.

something/NULLIF(column_name,0) 

Если значение column_name 0 - результат всего выражения будет NULL

+7

что-то вроде значения/COALESCE (NULLIF (column_name, 0), 1) будет работать, я полагаю – Akash

+0

Пробовал это с COALESCE, поскольку @Akash предложил, и он сделал работу –

+1

NULLIF работает точно так же, как предложил Yuiry - спасибо! –

1

Если вы хотите, чтобы делитель будет 1, когда счетчик равен нулю:

count(column_name) + 1 * (count(column_name) = 0)::integer 

Актерский из true до integer is 1.

+0

Приятный трюк, но я думаю, что утверждение случая может быть более очевидным. –

+0

'CASE' также быстрее, даже если он более подробный. –

12

Я понимаю, что это старый вопрос, но другое решение было бы использовать функции наибольшее:

greatest(count(column_name), 1) -- NULL and 0 are valid argument values 

Примечание: Мое предпочтение было бы либо возвратите NULL, как в ответе Эрвина и Юрия, или для его логического решения, обнаружив значение 0 до операции деления и вернув 0. В противном случае данные могут быть искажены с помощью 1.

+0

Я собираюсь использовать это, так как мой делитель - это «прошедшее время» для процесса, а 0, вероятно, означает долю секунды, поэтому По умолчанию я использую 0,01 минуты. Я сравниваю производительность процесса. – PhilHibbs

Смежные вопросы