SQL 比率(百分比)计算 - 除以零误差

SQL rate (percentage) calculation - division by zero error

已尝试使用 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?

谢谢!

您可以使用 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

这应该有效:

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 )