2015-01-09 66 views
9

对于每个独特的GroupId我希望得到每个IsGreen,IsRound,IsLoud条件和总行数的计数。计算组内的每个条件

的样本数据:

----------------------------------------------------- 
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 
+3

为什么不是这个由groupID'简单'组和'count'和'总和?' – xQbert

+0

如果你改变了所有的内部连接到左外连接您的代码将正常工作。 – Matt

回答

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] 
+0

Niceeee回答! –

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 
+2

'case'表达式在这种情况下有点多余。 – potashin