"case when" 内的聚合 - 执行顺序是什么?

aggregation inside "case when" - What's the executing order?

为什么这个简单的查询会导致“被零除”错误?

select 
case when b > 0 then sum(a / b) end
from (values (1,1),(2,1),(1,0),(2,0)) t (a,b)
group by b

我希望输出:

case
3
NULL

我唯一的解释是 postgres 在进行分组和评估案例之前计算总和。

参见documentation

[…] a CASE cannot prevent evaluation of an aggregate expression contained within it, because aggregate expressions are computed before other expressions in a SELECT list or HAVING clause are considered. For example, the following query can cause a division-by-zero error despite seemingly having protected against it:

SELECT CASE WHEN min(employees) > 0
            THEN avg(expenses / employees)
       END
FROM departments;

因此预计聚合表达式 sum(a/b) 在其他表达式之前计算。这不仅适用于 Postgresql,也适用于 Sql 服务器。

使用 NULLIF() 来避免这个问题,你不需要 CASE:

SELECT  
     SUM(a / NULLIF(b,0))
FROM 
    (values (1,1),(2,1),(1,0),(2,0)) t (a,b)
GROUP BY b
ORDER BY 1; -- first (and only) column