jimmyjambles
jimmyjambles

Reputation: 1670

Count each condition within group

For every unique GroupId I would like to get a count of each IsGreen, IsRound, IsLoud condition and a total number of rows.

Sample data:

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

Desired result:

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

I'm using the following code to create the table, the problem I'm having is that if any of the groups have no rows that match one of the conditions that group does not appear in the final table. What is the best way to accomplish what I want to do?

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

Upvotes: 9

Views: 357

Answers (2)

potashin
potashin

Reputation: 44581

You can use count to count rows per each [GroupId] and sum to count each property .

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

Upvotes: 16

Pரதீப்
Pரதீப்

Reputation: 93704

Use conditional Aggregate. Try this.

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 

Upvotes: 6

Related Questions