避免在PostgreSQL中被零除


80

我想在SELECT子句中执行除法。当我加入一些表并使用聚合函数时,我通常将null或零值用作分隔符。到目前为止,我只想出这种避免被零值和空值相除的方法。

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

我想知道是否有更好的方法?


4
用零除以以零除的方式不是问题。顺便说一句,count()永远不会返回null。
David Aldridge

我不知道!谢谢(你的)信息。
William Wino

Answers:


44

由于count()永不返回NULL(与其他聚合函数不同),您只需要抓住0情况(无论如何这是唯一有问题的情况):

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

引用有关聚合函数的手册:

应当注意,除了之外count,这些函数在未选择任何行时都将返回空值。


222

您可以使用NULLIF函数,例如

something/NULLIF(column_name,0)

如果值column_name是0-整个表达式的结果将为NULL


16
我想像value / COALESCE(NULLIF(column_name,0),1)这样的东西会起作用
Akash

与COALESCE尝试它作为@Akash建议,它所做的工作
ABD

3
这是许多零除问题的完美语义解决方案!有时您不希望除法是其他一些值,而根本不希望计算它!
LeoRochael

40

我意识到这是一个古老的问题,但是另一个解决方案是利用最大的功能:

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

注意: 我的偏好是返回一个NULL(如Erwin和Yuriy的答案一样),或者通过检测值0在除法运算之前并返回来从逻辑上解决这个问题0。否则,使用可能会误解数据1


我将使用此参数,因为除数是一个过程的“经过时间”,而0可能意味着几分之一秒,所以我将0.01分钟用作默认时间。我只是比较过程性能。
PhilHibbs

就可读性而言,这是我最简单的解决方案
Florent Destremau

5

另一种解决方案,避免被零除,而是替换为1

select column + (column = 0)::integer;

这真的很聪明。
lightyrs

3

如果要在计数为零时将分频器设为1,请执行以下操作:

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

true转换integer为1。


不错的窍门,但我认为案件陈述可能更明显。
David Aldridge

CASE即使更冗长,速度也更快。
Erwin Brandstetter
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.