我有现实世界的情况:
有“小屋”标识的小屋。人们可以住在小木屋里。 'person_age'表示每个人的年龄。
我试图找出每个小屋中有多少人住在35岁以上,并且该小屋中有多少人超过35岁,条件是我只想考虑搬进小屋的人特定的日期范围,我也想了解每个舱室的结果。
我有以下查询:
select
[house]
,count(case when person_age > 35 then 1 end) as [older than 35]
,(cast(count(case when person_age > 35 then 1 end) as float))/(count(case when person_age > 35 then 1 else 1 end)) as [percent older than 35]
from cabins
where
move_in_date >= '2014-02-01'
and move_in_date <= '2014-03-01'
group by [house]
有没有更好的方法来计算百分比字段,例如特定功能或其他什么?我认为它有效,但它太丑了。
我是否正确使用计数功能?它给了我我想要的东西,但我不确定。
答案 0 :(得分:2)
您的查询在逻辑中看起来没问题。我会这样写:
select [house],
sum(case when person_age > 35 then 1 else 0 end) as [older than 35],
avg(case when person_age > 35 then cast(1 as float) else 0
end) as [percent older than 35]
from cabins
where move_in_date >= '2014-02-01' and move_in_date <= '2014-03-01'
group by [house];
换句话说,您只需创建一个值为0.0或1.0的指标,并使用avg()
函数。
答案 1 :(得分:2)
您选择了非聚合以及两个聚合,因此您需要GROUP BY
,并且可以使用OVER()
上的SUM()
来获取Percent of total
}:
SELECT [house]
, COUNT(CASE WHEN person_age > 35 THEN 1 END) AS [older than 35]
, COUNT(CASE WHEN person_age > 35 THEN 1 END)*1.0/SUM(COUNT(CASE WHEN person_age > 35 THEN 1 END))OVER() AS [percent older than 35]
FROM cabins
WHERE move_in_date >= '2014-02-01'
AND move_in_date <= '2014-03-01'
GROUP BY [house]
更新:重新阅读我想你想要每个房子超过35人的百分比,所以简单地说:
SELECT [house]
, COUNT(CASE WHEN person_age > 35 THEN 1 END) AS [older than 35]
, COUNT(CASE WHEN person_age > 35 THEN 1 END)*1.0/COUNT(person_age) AS [percent older than 35]
FROM cabins
WHERE move_in_date >= '2014-02-01'
AND move_in_date <= '2014-03-01'
GROUP BY [house]
答案 2 :(得分:1)
您的代码存在以下几个问题:
1)这些计数没有条件,所以他们会给你所有小屋中超过35人的总数和所有小屋中超过35人的百分比(而你想要的是每个小屋中的这些数字)。要解决此问题,您需要添加&#34; GROUP BY [house]&#34;在你的where子句之后。这将告诉聚合函数(计数和百分比)仅查看每行的给定房屋。
2)您不需要在百分比字段的分母中使用案例陈述。 Count(*)做同样的事情。它应该是这样的:
(cast(count(case when person_age > 35 then 1 end) as float))/(count(*)) as [percent older than 35]
编辑:count(1)正如@Darka在评论中建议的那样也行。
答案 3 :(得分:1)
你可以稍微简化一下
select
[house]
,count(case when person_age > 35 then 1 end) as [older than 35]
,(cast(count(case when person_age > 35 then 1 end) as float))/(count(1)) as [percent older than 35]
from cabins
where
move_in_date between '2014-02-01' and '2014-03-01'
GROUP BY [house]