SQL Server-使用条件计算列并输出百分比

SQL Server-使用条件计算列并输出百分比,sql,sql-server,Sql,Sql Server,我了解真实世界的情况: 有小屋,用“房子”标识。人们可以住在小木屋里person_age'标识每个人的年龄 我试图找出35岁以上的人住在每一个小屋里,在那个小屋里有多少人比35岁大,我只想考虑在特定的日期范围内搬进机舱的人,我也想知道每个机舱的结果。 我有以下疑问: select [house] ,count(case when person_age > 35 then 1 end) as [older than 35] ,(cast(count(case when pers

我了解真实世界的情况:

有小屋,用“房子”标识。人们可以住在小木屋里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]
选择
[众议院]
,将(年龄大于35岁的情况下,1岁结束)计算为[大于35岁]
,(将(计算(当人员年龄>35岁时,则1个结束)作为浮动)/将(计算(当人员年龄>35岁时,则1个结束)作为[年龄大于35%的百分比]
从船舱
哪里
移入日期>='2014-02-01'

并将\u移入\u date代码中有几个问题:

1) 这些计数没有任何条件,因此它们将为您提供所有舱室中35岁以上的总人数以及所有舱室中35岁以上的人数百分比(而您需要的是每个舱室中的这些数字)。要解决这个问题,您需要在where子句之后添加一个“GROUPBY[house]”。这将告诉聚合函数(count和percentage)只查看每行的给定房屋

2) 在百分比字段的分母中不需要case语句。计数(*)也做同样的事情。应该是这样的:

(cast(count(case when person_age > 35 then 1 end) as float))/(count(*)) as [percent older than 35]

编辑:按@Darka在评论中的建议计算(1)也可以

您的代码有几个问题:

1) 这些计数没有任何条件,因此它们将为您提供所有舱室中35岁以上的总人数以及所有舱室中35岁以上的人数百分比(而您需要的是每个舱室中的这些数字)。要解决这个问题,您需要在where子句之后添加一个“GROUPBY[house]”。这将告诉聚合函数(count和percentage)只查看每行的给定房屋

2) 在百分比字段的分母中不需要case语句。计数(*)也做同样的事情。应该是这样的:

(cast(count(case when person_age > 35 then 1 end) as float))/(count(*)) as [percent older than 35]

编辑:按@Darka在评论中的建议计算(1)也可以

您的查询在逻辑上看起来正常。我会这样写:

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];
选择[house],
总和(当人的年龄大于35岁时,则1或0结束)为[大于35岁],
平均值(当人的年龄>35岁时,则将1作为浮动)或0
结束)作为[大于35%的百分比]
从船舱

其中move_in_date>='2014-02-01'和move_in_date您的查询在逻辑上看起来正常。我会这样写:

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];
选择[house],
总和(当人的年龄大于35岁时,则1或0结束)为[大于35岁],
平均值(当人的年龄>35岁时,则将1作为浮动)或0
结束)作为[大于35%的百分比]
从船舱

如果move_in_date>='2014-02-01'和move_in_date您选择的是一个非聚合以及两个聚合,因此您需要一个
分组依据,并且您可以在
SUM()
上使用
OVER()
来获得总的
百分比:

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岁的情况下,1岁结束)计算为[大于35岁]
,以[35岁以上的百分比]计算(35岁以上的情况下1岁)*1.0/和(35岁以上的情况下1岁以上的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况)
从船舱
其中移动日期>='2014-02-01'
并将_in_date 35然后1 END)移动为[大于35]
,计数(当人年龄>35岁时为1岁)*1.0/计数(人年龄)为[35岁以上的百分比]
从船舱
其中移动日期>='2014-02-01'

然后移动到日期您正在选择一个非聚合以及两个聚合,因此您需要一个
分组依据
,并且您可以在
SUM()
上使用
OVER()
来获得总的
百分比

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岁的情况下,1岁结束)计算为[大于35岁]
,以[35岁以上的百分比]计算(35岁以上的情况下1岁)*1.0/和(35岁以上的情况下1岁以上的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况下1岁的情况)
从船舱
其中移动日期>='2014-02-01'
并将_in_date 35然后1 END)移动为[大于35]
,计数(当人年龄>35岁时为1岁)*1.0/计数(人年龄)为[35岁以上的百分比]
从船舱
其中移动日期>='2014-02-01'

然后在日期中移动,你可以简化一点

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]

你可以简化一点

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]

count(如果person\u age>35,则1个else 1 end)
这部分可以是
count(1)
我假设您有一个
GROUP BY
子句,否则该语句甚至无法编译。天哪,您是对的。因为某种原因,它不在那里。
count(当person\u age>35岁时,则1个else 1结束)
这部分可以是
count(1)
我假设你有一个
GROUP BY
子句,否则该语句甚至无法编译。天哪,你是对的。因为某些原因,它不存在。我在写答案时完全忘记了avg()函数,但您的答案(以及问题)缺少GROUP BY子句。我在写答案时完全忘记了avg()函数,但您的答案(以及问题)缺少GROUP BY子句。您的答案(以及原始问题)缺少“分组依据”子句。我将
分组依据
放回。当字段为
空时,
计数(1)
也会计数吗?(这是我想要的。)此外,我注意到您将
计数(1)
放在山羊的
计数(人年龄)的地方
。他们还会计算相同的部分吗?count(1)将计算所有记录,不管发生什么。我更喜欢使用它然后计数(*),我们正在尝试计数记录,没有其他内容。您的答案(以及原始问题)缺少“分组依据”子句。我将
分组依据
放回。
是否会计算(1)
当字段为
null
?(这是我想要的)时也计数。另外,我注意到您将
计数(