目标:
找到高海拔机场(海拔> = 2000)的百分比, 机场表中的状态。
在查询中,将百分比列作为别名 percent_high_elevation_airports。
有人可以解释为什么以下2条SQL语句给出不同的结果:
正确的结果:
SELECT state,
100.0 * sum(CASE WHEN elevation >= 2000 THEN 1 ELSE 0 END) / count(*) as percentage_high_elevation_airports
FROM airports
GROUP BY state;
样本结果:
MS 0.0
MT 100.0
NC 11.1111111111111
ND 10.0
和错误的结果:
select
state,
100.0 * (sum(case when elevation >= 2000 then 1 else 0 end)/count(*)) as percentage_high_elevation_airports
from airports
group by 1;
样本结果:
MS 0.0
MT 100.0
NC 0.0
ND 0.0
唯一的区别是()在和周围的附加位置。
答案 0 :(得分:4)
我会这样写:
SELECT state,
AVG(CASE WHEN elevation >= 2000 THEN 100.0 ELSE 0 END) as percentage_high_elevation_airports
FROM airports
GROUP BY state;
问题是整数算术。一些数据库进行整数除法并返回整数。因此,1/2是0
而不是0.5
。某些数据库也将此应用于avg()
(但有些数据库甚至将整数除以数值平均值)。
我应该注意,这是特定于数据库的。
答案 1 :(得分:1)
您的问题不是关于查询的另一种/更好的解决方法
但是使用括号会导致错误的结果,对吗?
因为:
sum(case when elevation >= 2000 then 1 else 0 end)
结果为整数
根据定义,count(*)
是整数。
它们之间的除法是一个整数除法,它会截断任何十进制数字。
因此,您得到的是0
而不是0.5
或0.05
。
为避免出现这种情况,您可以像实乘以实数:100.0
,然后除以。
或者,您可以这样做:
sum(case when elevation >= 2000 then 1.0 else 0.0 end)
得出的总和是浮点数。
无论如何,请确保除法的至少一个操作数是实数。
答案 2 :(得分:0)
尝试以下方法-您需要更改括号的位置
select
state,
(100.0 * sum(case when elevation >= 2000 then 1 else 0 end))/count(*)) as percentage_high_elevation_airports
from airports
group by 1