计算组内的每个条件

时间:2015-01-09 18:08:45

标签: sql sql-server count group-by aggregate-functions

对于每个唯一的GroupId,我想计算每个IsGreenIsRoundIsLoud条件和总行数。

示例数据:

-----------------------------------------------------
 id | ItemId | GroupId | IsGreen | IsRound | IsLoud
----+--------+---------+---------+---------+---------
  1 |  1001  |    1    |    0    |    1    |    1
  2 |  1002  |    1    |    1    |    1    |    0
  3 |  1003  |    2    |    0    |    0    |    0
  4 |  1004  |    2    |    1    |    0    |    1
  5 |  1005  |    2    |    0    |    0    |    0
  6 |  1006  |    3    |    0    |    0    |    0
  7 |  1007  |    3    |    0    |    0    |    0

期望的结果:

 ----------------------------------------------------------
 GroupId | TotalRows | TotalGreen | TotalRound | TotalLoud
 --------+-----------+------------+------------+-----------
    1    |     2     |     1      |     2      |     1
    2    |     3     |     1      |     0      |     1
    3    |     2     |     0      |     0      |     0

我使用以下代码创建表格,我遇到的问题是,如果任何组没有与最终表格中没有出现的条件之一相匹配的行。完成我想要做的最好的方法是什么?

SELECT total.GroupId
     , total.[Count] AS TotalRows
     , IsGreen.[Count] AS TotalGreen
     , IsRound.[Count] AS TotalRound
     , IsLoud.[Count] AS TotalLoud
FROM (
    SELECT GroupId
         , count(*) AS [Count]
    FROM TestData
    GROUP BY GroupId
) TotalRows
INNER JOIN (
    SELECT GroupId
         , count(*) AS [Count]
    FROM TestData
    WHERE IsGreen = 1
    GROUP BY GroupId
) IsGreen ON IsGreen.GroupId = TotalRows.GroupId
INNER JOIN (
    SELECT GroupId
         , count(*) AS [Count]
    FROM TestData
    WHERE IsRound = 1
    GROUP BY GroupId
) IsRound ON IsRound.GroupId = TotalRows.GroupId
INNER JOIN (
    SELECT GroupId
         , count(*) AS [Count]
    FROM TestData
    WHERE IsLoud = 1
    GROUP BY GroupId
) IsLoud ON IsLoud.GroupId = TotalRows.GroupId

2 个答案:

答案 0 :(得分:16)

您可以使用count计算每个[GroupId]sum的行数,以计算每个属性。

select [GroupId]
     , count([GroupId]) as [TotalRows]
     , sum([IsGreen]) as [TotalGreen]
     , sum([IsRound]) as [TotalRound]
     , sum([IsLoud]) as [TotalLoud]
from [TestData]
group by [GroupId]

答案 1 :(得分:6)

使用conditional Aggregate。试试这个。

SELECT GroupId,
       Count(GroupId) TotalRows,
       Count(CASE WHEN IsGreen = 1 THEN 1 END) TotalGreen,
       Count(CASE WHEN IsRound = 1 THEN 1 END) TotalRound,
       Count(CASE WHEN IsLoud = 1 THEN 1 END) TotalLoud
FROM   tablename
GROUP  BY GroupId