How to transpose data in postgresql
Suppose you have a table tbl_sales as below:
Country | Category | date | sales |
---|---|---|---|
USA | FOOD | 12/30/2017 | 1254 |
USA | FOOD | 09/30/2017 | 1154 |
USA | FOOD | 06/30/2017 | 1200 |
USA | FOOD | 03/30/2017 | 1500 |
USA | TOYS | 12/30/2017 | 1478 |
USA | TOYS | 09/30/2017 | 5684 |
USA | TOYS | 06/30/2017 | 4859 |
USA | TOYS | 03/30/2017 | 1548 |
and you have to transpose date into columns of 4 quarters.
First create rank function to distinct the quarters from date:
select row_number() over (partition by country, category, sales,
date_part('year', date) order by country, category asc, sales, date desc ) as row_num,* from tbl_sales
above query will add row_num column as shown below:
row_num | country | category | date | sales |
---|---|---|---|---|
1 | USA | FOOD | 12/30/2017 | 1254 |
2 | USA | FOOD | 09/30/2017 | 1154 |
3 | USA | FOOD | 06/30/2017 | 1200 |
4 | USA | FOOD | 03/30/2017 | 1500 |
1 | USA | TOYS | 12/30/2017 | 1478 |
2 | USA | TOYS | 09/30/2017 | 5684 |
3 | USA | TOYS | 06/30/2017 | 4859 |
On top of above query use case statement to create 4 quarter's columns
select e.country, e.category, e.sales, e.date,
case when row_num= 1 then company_actual end as Q1,
case when row_num= 2 then company_actual end as Q2,
case when row_num= 3 then company_actual end as Q3,
case when row_num= 4 then company_actual end as Q4 from
(
select row_number() over (partition by country, category, sales, date_part('year', date) order by country, category asc, sales, date desc ) as row_num , * from tbl_sales
) e order by 1,2
above query will generate below output:
row_num | country | category | date | sales | Q1 | Q2 | Q3 | Q4 |
---|---|---|---|---|---|---|---|---|
1 | USA | FOOD | 12/30/2017 | 1254 | 1254 | |||
2 | USA | FOOD | 09/30/2017 | 1154 | 1154 | |||
3 | USA | FOOD | 06/30/2017 | 1200 | 1200 | |||
4 | USA | FOOD | 03/30/2017 | 1500 | 1500 | |||
1 | USA | TOYS | 12/30/2017 | 1478 | 1478 | |||
2 | USA | TOYS | 09/30/2017 | 5684 | 5684 | |||
3 | USA | TOYS | 06/30/2017 | 4859 | 4859 | |||
4 | USA | TOYS | 03/30/2017 | 1548 | 1548 |
Now we just have to use group by query to get final result:
select country, category,
sum(Q1) Q1,
sum(Q2) Q2,
sum(Q3) Q3,
sum(Q4) Q4 from
(
select e.country, e.category, e.sales,
case when row_num= 1 then company_actual end as Q1,
case when row_num= 2 then company_actual end as Q2,
case when row_num= 3 then company_actual end as Q3,
case when row_num= 4 then company_actual end as Q4 from
select row_number() over (partition by country, category, sales, date_part('year', date) order by country, category asc, sales, date desc ) as row_num,
* from tbl_sales ) e
order by 1,2 ) B
group by 1,2 order by 1,2
Here we get transposed output:
country | category | Q1 | Q2 | Q3 | Q4 |
---|---|---|---|---|---|
USA | FOOD | 1254 | 1154 | 1200 | 1500 |
USA | TOYS | 1478 | 5684 | 4859 | 1548 |
Comments
Post a Comment