首页 > 解决方案 > 为逐月变化创建数据透视表

问题描述

我有从查询返回的这些记录

+---------+--------------+-----------+----------+
| Country | other fields |   sales   |   date   |
+---------+--------------+-----------+----------+
| US      | 1            |  $100.00  | 01/01/21 |
| CA      | 1            |  $100.00  | 01/01/21 |
| UK      | 1            |  $100.00  | 01/01/21 |
| FR      | 1            |  $100.00  | 01/01/21 |
| US      | 1            |  $200.00  | 01/02/21 |
| CA      | 1            |  $200.00  | 01/02/21 |
| UK      | 1            |  $200.00  | 01/02/21 |
| FR      | 1            |  $200.00  | 01/02/21 |

我想显示从一个月到前一个月的销售变化,如下所示:

| Country | 01/02/21     | 01/01/21  | Var%     |
| US      |  $200.00     |  $100.00  | 100%     |
| CA      |  $200.00     |  $100.00  | 100%     |
| FR      |  $200.00     |  $100.00  | 100%     |
+---------+--------------+-----------+----------+

如何使用 Postgres 查询来完成?

标签: postgresqlpivot

解决方案


如果你总是只比较两个月:

select country
    , sum(sales) filter (where date ='01/01/21')  month1
    , sum(sales) filter (where date ='01/02/21')  month2
    , ((sum(sales) filter (where date ='01/02/21') /sum(sales) filter (where date ='01/01/21')) - 1) * 100 var
from tablename
where date in ('01/01/21' , '01/02/21')
group by country

您也可以crosstab从与上述查询基本相同的 tablefunc 扩展中查看。

CREATE EXTENSION IF NOT EXISTS tablefunc;

select * ,("01/02/21" /"01/01/21") - 1) * 100 var 
from(
select * from crosstab ('select Country,date , sales from tablename')
as ct(country varchar(2),"01/01/21" money , "01/02/21" money)
) t

有关交叉表的更多信息,请参阅tablefunc

但是如果你想在行而不是列中显示日期,你可以很容易地将它概括为所有日期:

select * 
   , ((sales / LAG(sales,1,1) over (partition by country order by date)) -1)* 100  var
from 
country 

推荐阅读