带有百分比和聚合函数的SQL查询

时间:2013-03-26 17:29:32

标签: sql aggregate-functions aggregate

我正在尝试编写一个SQL查询,我需要得分数> 3按县名,然后对于该名单上的县,我需要产生一定比例的房间的百分比<所以我需要三个栏目,县名,得分数> 3按县,%的房间得分< 3由县

    SELECT County = c.Description, [Score > 3] = count(s.Score),  
  ((select count(room.Name) where s.Score< 3) /( select count(room.Name) ) * 100)
    FROM Sites AS s
    inner join Profiles as p on s.Profile_Id = p.Id
    inner join Counties as c on p.County_Id = c.Id
    inner join Rooms as room on s.Id = room.Site_Id
    where s.Score > 3
    Group By c.Description

3 个答案:

答案 0 :(得分:0)

[Score > 3] = count(s.Score) 

...

where s.Score > 3

不需要这两种说法。实际上你的Where子句将所有操作限制为s.score&gt; 3,当你还试图从分数<3中提取数据时,这并不理想。

如果您正在尝试计算s.Score&gt; 3及其位置<3的情况,则需要使用CASE语句

SELECT SUM(CASE WHEN s.score < 3 THEN 1  ELSE 0 END) AS Hiscores,  
SUM(CASE WHEN s.score >    3 THEN 1  ELSE 0 END) /count(s.scores) AS percentLowScores

这应该这样做

  SELECT c.Description County, 
  SUM(CASE WHEN s.score < 3 THEN 1  ELSE 0 END) AS Hiscores,  
  SUM(CASE WHEN s.score > 3 THEN 1  ELSE 0 END) /count(s.scores) AS percentLowScores

    FROM Sites AS s
    inner join Profiles as p on s.Profile_Id = p.Id
    inner join Counties as c on p.County_Id = c.Id
    inner join Rooms as room on s.Id = room.Site_Id

    Group By c.Description

答案 1 :(得分:0)

使用Cast

SELECT County = c.Description, [Score > 3] = count(s.Score), 
    ( Cast(select count(room.Name) where s.Score < 3 ) as float / ( select count(room.Name) ) * 100)
    FROM Sites AS s
    inner join Profiles as p on s.Profile_Id = p.Id
    inner join Counties as c on p.County_Id = c.Id
    inner join Rooms as room on s.Id = room.Site_Id
    where s.Score > 3
    Group By c.Description

答案 2 :(得分:0)

我认为你过度使问题复杂化,而不是子选择你可以使用HAVING子句限制返回的数据,然后在CASE中使用COUNT

SELECT  County = c.Description,
        [Score > 3] = COUNT(CASE WHEN Sites.Score > 3 THEN 1 END),
        [% Score < 3] = 100.0 * COUNT(CASE WHEN Sites.Score < 3 THEN 1 END) / COUNT(1)
FROM    Sites
        INNER JOIN Profiles
            ON Sites.Profile_Id = Profiles.Id
        INNER JOIN Counties 
            ON Profiles.County_Id = Counties.Id
        INNER JOIN Rooms 
            ON Sites.Id = Rooms.Site_Id
GROUP BY c.Description
HAVING  COUNT(CASE WHEN Sites.Score > 3 THEN 1 END) > 0;

<强> Demo on SQL Fiddle

修改

SELECT  County = c.Description,
        [Score > 3] = COUNT(CASE WHEN Sites.Score > 3 THEN 1 END),
        [% Score < 3] = 100.0 * SUM(CASE WHEN Sites.Score < 3 THEN 1 END) / COUNT(*),
        [Score > 3] = SUM(CASE WHEN Sites.Score > 3 THEN RoomCount ELSE 0 END),
        [% Score < 3] = 100.0 * SUM(CASE WHEN Sites.Score < 3 THEN RoomCount ELSE 0 END) / SUM(RoomCount)
FROM    Sites
        INNER JOIN Profiles
            ON Sites.Profile_Id = Profiles.Id
        INNER JOIN Counties 
            ON Profiles.County_Id = Counties.Id
        INNER JOIN 
        (   SELECT Site_Id, RoomCount = COUNT(*)
            FROM   Rooms 
            GROUP BY Site_Id
        ) Rooms
            ON Sites.Id = Rooms.Site_Id
GROUP BY c.Description
HAVING  COUNT(CASE WHEN Sites.Score > 3 THEN 1 END) > 0;