My input table has count of values for events belonging to specific categories for every year.
| events | year | category |
|---|---|---|
| 16 | 2022 | A |
| 13 | 2022 | B |
| 3 | 2022 | C |
| 113 | 2022 | D1 |
| 1 | 2022 | D2 |
| 2 | 2022 | D3 |
| 5 | 2023 | A |
| 8 | 2023 | B |
I need to show a sum of the events for each category for each year, in the specific case I'd also need to aggregate D1 D2 D3 together).
Expected Output:
| year | events-total | category A | category B | category C | category D |
|---|---|---|---|---|---|
| 2022 | 148 | 16 | 13 | 3 | 116 |
| 2023 | 13 | 5 | 8 | 0 | 0 |
The main problem of my attempts comes from the fact that there are challenges from: 1 - years that dont have events in certain categories, 2 - the years are only 2 for now, but will grow as time goes by
I tried breaking the sql with several views but cannot preview in future years the cases where some categories don't have values.
I'd like to have a sql query that handles future cases.
Thanks for any help.
CodePudding user response:
This is the case of a pivoting task.
In your specific case the CASE expressions help you to gather specific count of events to be summed up, then you can aggregate on your year_ values. You can detect the D values with the LIKE operator.
SELECT year_,
SUM(events_) AS events_total,
SUM(CASE WHEN category = 'A' THEN events_ ELSE 0 END) AS categoryA,
SUM(CASE WHEN category = 'B' THEN events_ ELSE 0 END) AS categoryB,
SUM(CASE WHEN category = 'C' THEN events_ ELSE 0 END) AS categoryC,
SUM(CASE WHEN category LIKE 'D%' THEN events_ ELSE 0 END) AS categoryD
FROM tab
GROUP BY year_
Check the demo here.
Using the FILTER operator, combined with the COALESCE function, would come out like this:
SELECT year_,
SUM(events_) AS events_total,
COALESCE(SUM(events_) FILTER(WHERE category = 'A' ), 0) AS catA,
COALESCE(SUM(events_) FILTER(WHERE category = 'B' ), 0) AS catB,
COALESCE(SUM(events_) FILTER(WHERE category = 'C' ), 0) AS catC,
COALESCE(SUM(events_) FILTER(WHERE category LIKE 'D%'), 0) AS catD
FROM tab
GROUP BY year_
Check the demo here.
