【问题标题】:Avoid division by zero in PostgreSQL避免在 PostgreSQL 中被零除
【发布时间】:2013-07-14 22:03:40
【问题描述】:

我想在 SELECT 子句中执行除法。当我加入一些表并使用聚合函数时,我经常将空值或零值作为分隔符。至于现在,我只提出了这种避免除以零和空值的方法。

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

我想知道是否有更好的方法来做到这一点?

【问题讨论】:

  • 除以空值不是除以零那样的问题。顺便说一句,count() 永远不会返回 null。
  • 我不知道!谢谢你的信息。

标签: sql postgresql null aggregate-functions divide-by-zero


【解决方案1】:

你可以使用NULLIF函数例如

something/NULLIF(column_name,0)

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

【讨论】:

  • 我想像 value/COALESCE(NULLIF(column_name,0), 1) 这样的东西会起作用
  • 按照@Akash 的建议使用 COALESCE 进行了尝试,并且成功了
  • 这是许多除零问题的完美语义解决方案!有时您不希望除法是其他值,而是根本不计算它!
【解决方案2】:

由于 count() 永远不会返回 NULL(与其他聚合函数不同),您只需要捕获 0 情况(无论如何这是唯一有问题的情况)。因此,您的查询已简化:

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

或者更简单,但是,NULLIF()like Yuriy provided

Quoting the manual about aggregate functions:

需要注意的是,除了count,这些函数都返回一个 未选择任何行时为空值。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 我将使用它,因为我的除数是一个进程的“经过时间”,0 可能意味着几分之一秒,所以我将使用 0.01 分钟作为默认时间.我只是在比较过程性能。
    • 就可读性而言,这对我来说是最简单的解决方案
    【解决方案4】:

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

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

    【讨论】:

    • 这真是太聪明了。
    【解决方案5】:

    如果你希望在计数为零时除法器为1:

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

    trueinteger 的演员是1。

    【讨论】:

    • 不错的技巧,但我认为案例陈述可能更明显。
    • CASE 也更快,即使更冗长。
    猜你喜欢
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    相关资源
    最近更新 更多