Reputation: 21
I'm hoping someone can help me with a SQL select statement for the following problem:
I have the following data in a table:
date | color |
---|---|
01/23/2023 | RED |
01/23/2023 | BLUE |
01/23/2023 | GREEN |
01/23/2023 | GREEN |
01/23/2023 | RED |
01/23/2023 | BLUE |
01/23/2023 | GREEN |
01/24/2023 | BLUE |
01/24/2023 | GREEN |
01/24/2023 | BLUE |
01/24/2023 | RED |
01/25/2023 | GREEN |
01/25/2023 | BLUE |
01/25/2023 | GREEN |
01/25/2023 | BLUE |
and I would like to produce this:
date | RED | BLUE | GREEN |
---|---|---|---|
01/23/2023 | 2 | 2 | 3 |
01/24/2023 | 1 | 2 | 1 |
01/25/2023 | 0 | 2 | 2 |
I'll have the exact colors so I don't need that to be determined. Sorry but I don't have any idea of how to even to beginning writing this select statement.
Thanks.
Upvotes: 0
Views: 55
Reputation: 3494
First, it would be mighty helpful if you posted your example data as "Readily Consumable Data" on future posts. Like this for this post...
--===== Create "Readily Consumable Data to help those
-- That would help you.
DROP TABLE IF EXISTS #TestTable;
GO
SELECT *
INTO #TestTable
FROM (VALUES
('01/23/2023','RED')
,('01/23/2023','BLUE')
,('01/23/2023','GREEN')
,('01/23/2023','GREEN')
,('01/23/2023','RED')
,('01/23/2023','BLUE')
,('01/23/2023','GREEN')
,('01/24/2023','BLUE')
,('01/24/2023','GREEN')
,('01/24/2023','BLUE')
,('01/24/2023','RED')
,('01/25/2023','GREEN')
,('01/25/2023','BLUE')
,('01/25/2023','GREEN')
,('01/25/2023','BLUE')
)d(date,color)
;
Giving credit where credit is certainly due, both @Learning and @Horaciux gave excellent CROSSTAB answers that do exactly what you ask.
In anticipation of what the folks that asked originally ask you for this output will likely ask of you next, you can also easily add a "DateTotal" and a "ColorTotal". CROSSTABs do make this easy. PIVOTs? No so much and I'm not going to demo that.
Here's the code to include the additional DateTotal column and ColorTotal row. I also converted the CASE statements to IIF to make things less busy. To be sure, though, IIF resolves to CASE statements behind the scenes and that means there's no performance advantage. If you hate IIF, like some do, just change them back to CASE and Bob's your uncle. :D
SELECT Date = IIF(GROUPING(date) = 1, 'Total',CONVERT(CHAR(10),date,101))
,Red = SUM(IIF(color = 'RED' ,1,0))
,Blue = SUM(IIF(color = 'BLUE' ,1,0))
,Green = SUM(IIF(color = 'GREEN',1,0))
,DateTotal = COUNT(*)
FROM #TestTable
GROUP BY date WITH ROLLUP
ORDER BY GROUPING(date),Date
;
That produces the following output...
Upvotes: 0
Reputation: 610
You can use CASE WHEN SUM
SELECT
edate,
SUM (CASE WHEN color = 'RED' THEN 1 ELSE 0 END) AS RED,
SUM (CASE WHEN color = 'BLUE' THEN 1 ELSE 0 END) AS BLUE,
SUM (CASE WHEN color = 'GREEN' THEN 1 ELSE 0 END) AS GREEN
FROM tablename
GROUP BY edate
Upvotes: 1
Reputation: 6477
SELECT date,
SUM(CASE WHEN color = 'RED' THEN 1 ELSE 0 END) AS RED,
SUM(CASE WHEN color = 'BLUE' THEN 1 ELSE 0 END) AS BLUE,
SUM(CASE WHEN color = 'GREEN' THEN 1 ELSE 0 END) AS GREEN
FROM table1
GROUP BY date
ORDER BY date;
Upvotes: 1