【问题标题】:SQL rate (percentage) calculation - division by zero errorSQL 率(百分比)计算 - 除以零错误
【发布时间】:2018-08-25 11:17:54
【问题描述】:

尝试使用 NULLIF 或 IFNULL 函数,但仍收到被零除的消息。

SELECT 
client_id
,COUNT(distinct CASE WHEN status = 'failed' THEN id END) AS count_FAILS
,COUNT(distinct CASE WHEN status = 'completed' THEN id END) AS count_COMPLETED
,COUNT(distinct CASE WHEN status IN ('failed') THEN id END)
 /CAST(COUNT(CASE WHEN status = 'completed' THEN id END) AS FLOAT) 

FROM journey
GROUP BY 1

示例数据库和查询 https://dbfiddle.uk/?rdbms=postgres_10&fiddle=efc0cd25843e852ab7a3aa8fe49e6986

此类查询是否需要 distinct ?

谢谢!

【问题讨论】:

    标签: sql postgresql rate


    【解决方案1】:

    这应该可行:

    COUNT(distinct CASE WHEN status IN ('failed') THEN id END) * 1.0 /
    NULLIF(COUNT(CASE WHEN status = 'completed' THEN id END), 0)
    

    您可以转换为浮点数。我更喜欢只使用* 1.0

    我注意到count_completed 的定义使用了count(distinct),但这个比率没有。这可能是一个错误。

    我更可能想要整体失败状态的比例,而不是比例。如果这是可以接受的并且COUNT(DISTINCT) 对这两个计数都不是必需的,那么这可以简化为:

    avg( (status = 'failed')::int )
    

    【讨论】:

    • 感谢您的回复。有没有一种快速的方法来替换 value = 1 而不是 0 来接收速率,而不是空单元格?
    • @snowboi 。 . .如果我理解您的评论,您可以使用coalesce(<expression>, 1)
    【解决方案2】:

    你可以使用NULLIF:

    ,COUNT(distinct CASE WHEN status IN ('failed') THEN id END)/
     NULLIF(CAST(COUNT(CASE WHEN status = 'completed' THEN id END) AS FLOAT),0) 
    

    DBFidde Demo


    我会将整个查询重写为:

    SELECT 
      client_id
      ,COUNT(distinct id) FILTER(WHERE status = 'failed') AS count_FAILS
      ,COUNT(distinct id) FILTER(WHERE status = 'completed') AS count_COMPLETED
      ,COUNT(distinct id) FILTER(WHERE status = 'failed')
       /NULLIF(1.0 * COUNT(distinct id) FILTER(WHERE status = 'completed'),0)
    FROM journey
    GROUP BY client_id;
    

    DBFiddle Demo2

    【讨论】:

    • 谢谢,卢卡斯! Demo和Demo2有什么区别?我看不到任何
    • @snowboi 显式 GROUP BY client_id 代替 1 并使用 COUNT(distinct id) FILTER(WHERE status = 'failed') 代替 CASE
    • 我的意思是无法发现结果的差异。对于大型数据集,这种方法是否更快?我认为在 GROUP BY 语句中使用 1 或 client_id 没有区别
    • @snowboi 如果您不关心位置语法,那么不会。 ORDER BY 1/GROUP BY 1 可能被视为反模式 - 品味问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 2016-09-04
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多