PostgreSQL:如何避免被零除?
PostgreSQL: How to avoid divide by zero?
我试图从 table occu_cap 中获取平均占用率,但我收到错误“错误:被零除”。两列中都有 0 个值。
我一直在考虑使用 NULLIF(column_name,0) 但我不知道如何在下面的代码中实现它。
SELECT *, AVG((occupancy/capacity) * 100)) AS avg_occupancy_rate
FROM occu_cap
GROUP BY 1,2,3
示例数据和预期结果:
occupancy
capacity
avg_occupancy_rate
1232
1630
75.58
0
658
null
0
0
null
错误是由于 capacity
是 0
值(这可能不允许来自数学除法),如果您的预期结果是 0
而 capacity
是 0
来自 occupancy/capacity
AVG((COALESCE(occupancy / NULLIF(capacity,0), 0) * 100))
编辑
你可以尝试用CASE WHEN
表达式来判断值是否为零然后return NULL
AVG(CASE WHEN capacity <> 0 AND occupancy <> 0 THEN ((occupancy::decimal/capacity * 1.0) * 100) END)
如果您想显示所有列,您可以尝试使用 window 函数。
SELECT *,AVG(CASE WHEN capacity <> 0 AND occupancy <> 0 THEN ((occupancy::decimal/capacity * 1.0) * 100) END) OVER(PARTITION BY id)
FROM occu_cap
注意
如果您的 occupancy
或 capacity
不是 float-point 号码的类型,我们需要 CAST
将其作为 float-point 号码,然后再执行 AVG
我试图从 table occu_cap 中获取平均占用率,但我收到错误“错误:被零除”。两列中都有 0 个值。 我一直在考虑使用 NULLIF(column_name,0) 但我不知道如何在下面的代码中实现它。
SELECT *, AVG((occupancy/capacity) * 100)) AS avg_occupancy_rate
FROM occu_cap
GROUP BY 1,2,3
示例数据和预期结果:
occupancy | capacity | avg_occupancy_rate |
---|---|---|
1232 | 1630 | 75.58 |
0 | 658 | null |
0 | 0 | null |
错误是由于 capacity
是 0
值(这可能不允许来自数学除法),如果您的预期结果是 0
而 capacity
是 0
来自 occupancy/capacity
AVG((COALESCE(occupancy / NULLIF(capacity,0), 0) * 100))
编辑
你可以尝试用CASE WHEN
表达式来判断值是否为零然后return NULL
AVG(CASE WHEN capacity <> 0 AND occupancy <> 0 THEN ((occupancy::decimal/capacity * 1.0) * 100) END)
如果您想显示所有列,您可以尝试使用 window 函数。
SELECT *,AVG(CASE WHEN capacity <> 0 AND occupancy <> 0 THEN ((occupancy::decimal/capacity * 1.0) * 100) END) OVER(PARTITION BY id)
FROM occu_cap
注意
如果您的 occupancy
或 capacity
不是 float-point 号码的类型,我们需要 CAST
将其作为 float-point 号码,然后再执行 AVG