Presto中SUM/COUNT踩坑
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Presto中SUM/COUNT踩坑相关的知识,希望对你有一定的参考价值。
参考技术A 原因:在presto中:两个value相除,至少有一个为浮点数才能返回正确结果解决方案:转为浮点型
(1)select sum(case when storecode = '15' then 1 else 0 end)*1.00 / count(1) from orders;
(2)cast(value AS type)
select * from table where date=20210101
在hive中正常执行,presto中会报错:operator equal(varchar, bigint) are not registered
原因:Presto不支持隐式转换,要求什么格式的参数,就一定得是什么格式的参数
改为select * from table where date=‘20210101’
在kylin中跑sum()/count() 和在presto中跑相同的sum/count结果不一致,原因分析:发现在kylin中count字段是不忽略null值的,应该怎么解决kylin中的这个问题????(KYLIN中没有avg函数,真是不够用)
目前的方法有:
重新构建一个cube(忽略null值的)
更改avg的口径问题(不可取....)
更改cube中null字段的数据类型
聚合case语句中sum和count的区别
【中文标题】聚合case语句中sum和count的区别【英文标题】:Difference between sum and count in aggregate case statement 【发布时间】:2020-12-12 16:51:13 【问题描述】:我在下面有一个查询:
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,对吗?
谢谢!
【问题讨论】:
正确。Count
会得到相同的结果。
我不同意,无论它的值是 0 还是 1,Count 仍然会计算行,而 sum 将求和,即如果值如果条件为真三次,那么它将返回 3,而 count 将返回数量行,无论条件是真还是假。
sum
与count(*) filter (where e.salary > 10000) ....
相同
【参考方案1】:
我们用过滤子句有条件地计数:
COUNT(*) FILTER (WHERE e.salary > 100000)
其他一些 dBMS 不支持过滤子句。在这里,我们通过使用CASE WHEN
自己评估表达式来使用变通方法,并使用COUNT
或SUM
来添加匹配项。以下是一些方法:
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 确实支持过滤子句,您应该使用 COUNT(*) FILTER (...)
。
【讨论】:
【参考方案2】:如果您只是将 sum
替换为 count
,您会得到不同的结果,因为 0 与 1 一样多。
正如其他人所提到的,最优雅的编写方式是 FILTER
子句,但您也可以这样做:
count(CASE WHEN e.salary > 100000 THEN 0 END)
这会起作用,因为(大多数)聚合函数会忽略 NULL 值。
【讨论】:
【参考方案3】:大概,员工不在多个部门,所以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)
通常比其他聚合函数贵一点。
【讨论】:
以上是关于Presto中SUM/COUNT踩坑的主要内容,如果未能解决你的问题,请参考以下文章