postgresql 汇总case语句中sum和count之间的差异

polhcujo  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(4)|浏览(178)

我有一个查询如下:

SELECT 
       d.name, 
      SUM(CASE WHEN e.salary > 100000 THEN 1 ELSE 0 END)
        / COUNT(DISTINCT e.id)
        AS pct_above_100k,
      COUNT(DISTINCT e.id) AS c
FROM employees e JOIN departments d ON e.department_id = d.id
GROUP BY 1
HAVING COUNT(*) > 10
ORDER BY 2 DESC

字符串
我在这里使用了sum,但是如果我使用count,会有什么不同吗?
我知道count计算的是一个值存在的次数,sum计算的是实际值的总和,但是在这里,因为我的条件是如果薪水> 100000,那么它无论如何都会将其视为1,对吗?
谢谢你,谢谢

yrwegjxp

yrwegjxp1#

我们使用filter子句有条件地计数:

COUNT(*) FILTER (WHERE e.salary > 100000)

字符串
其他一些dBMS不支持filter子句。这里我们使用解决方案,通过使用CASE WHEN评估表达式,然后使用COUNTSUM添加匹配项。这里有一些方法可以做到这一点:

SUM(CASE WHEN e.salary > 100000 THEN 1 ELSE 0 END)
COUNT(CASE WHEN e.salary > 100000 THEN 1 ELSE NULL END)
COUNT(CASE WHEN e.salary > 100000 THEN 1 END)
COUNT(CASE WHEN e.salary > 100000 THEN 'count this' END)


因为PostgreSQL支持filter子句,所以你应该使用COUNT(*) FILTER (...)

js81xvg6

js81xvg62#

如果你只是用count替换sum,你会得到一个不同的结果,因为0和1一样多。
最优雅的编写方式是FILTER子句,正如其他人所提到的,但您也可以这样做:

count(CASE WHEN e.salary > 100000 THEN 0 END)

字符串
这是可行的,因为NULL值被(大多数)聚合函数忽略。

qvtsj1bj

qvtsj1bj3#

假设员工不在多个部门中,那么count(distinct)是不必要的。
这意味着代码可以更简单地写为:

AVG(CASE WHEN e.salary > 100000 THEN 1 ELSE 0 END) AS pct_above_100k,

字符串
或者:

AVG( (e.salary > 100000)::int ) AS pct_above_100k,


这将比其他方法更有效,因为COUNT(DISTINCT)通常比其他聚合函数更昂贵。

h9vpoimq

h9vpoimq4#

我想你可以把它简化为:SUM(即薪水> 100000)虽然我不知道为什么这是有效的。
而如果你使用了“”,你就必须使用“WHERE”作为条件。

相关问题