I have some data
John has sum of money for the year = 30
Larry has sum of money for the year = 60.
Usually, the results in the database show like this...
id | name | yearly sum |
---|---|---|
1 | john | 30 |
2 | larry | 60 |
so I want it broken down like this without personally inserting the values myself
id | name | jan | feb | mar | apr | may |
---|---|---|---|---|---|---|
1 | john | 10 | 5 | 4 | 6 | 5 |
2 | larry | 20 | 15 | 4 | 6 | 15 |
sample of the original data.
Employee | company | contributions | months contributed on |
---|---|---|---|
John | Walmart | 10 | January |
John | Walmart | 5 | Feb |
John | Walmart | 4 | March |
John | Walmart | 6 | Apr |
John | Walmart | 5 | May |
Larry | Amazon | 20 | January |
Larry | Amazon | 15 | Feb |
Larry | Amazon | 4 | March |
Larry | Amazon | 6 | Apr |
Larry | Amazon | 15 | May |
1 Answer 1
This is commonly referred to as a pivot. I'm not a PostrgreSQL expert, but this style of query is pretty easy to effect in virtually all SQL-compliant database management systems.
First, we'll create a table:
CREATE TABLE contributions
(
Employee varchar(50)
, Company varchar(50)
, Contributions int
, Contribution_Month varchar(10)
);
And insert some values into it:
INSERT INTO contributions (Employee, Company, Contributions, Contribution_Month)
VALUES
('John', 'Walmart', 10, 'January')
, ('John', 'Walmart', 5, 'February')
, ('Larry', 'Amazon', 20, 'January')
, ('Larry', 'Amazon', 15, 'February')
Here's the "pivot" bit:
SELECT
totals.Employee
, SUM(totals.January) AS January
, SUM(totals.February) AS February
FROM (
SELECT
Employee
, CASE WHEN Contribution_Month = 'January' THEN Contributions ELSE 0 END AS January
, CASE WHEN Contribution_Month = 'February' THEN Contributions ELSE 0 END AS February
FROM contributions
) totals
GROUP BY totals.Employee;
And the results:
employee | january | february |
---|---|---|
John | 10 | 5 |
Larry | 20 | 15 |
I've only included January and February since the other months would just be rote repetition, but you should be able to extend it to include the other months without much work.
PostgreSQL offers the crosstab table function to produce a pivot table, which you construct like this:
SELECT
ct.Employee
, ct.January
, ct.February
FROM
crosstab
(
'SELECT Employee, Contribution_Month, Contributions FROM contributions'
) AS ct
(
employee varchar(50)
, January int
, February int
);
The output looks exactly the same as my example above, so I'll not repeat it here.
Here is a DB Fiddle for the above minimal, complete and verifiable example.