Search code examples
sqlpostgresqlcrosstab

Postgres Crosstab query Dynamic pivot


Does any one know how to create the following crosstab in Postgres?

For example I have the following table:

Store      Month        Sales
A          Mar-2020     100
A          Feb-2020     200
B          Mar-2020     400
B          Feb-2020     500
A          Jan-2020     400
C          Apr-2020     600

I would like the query to return the following crosstab, the column headings should not be hardcoded values but reflect the values in "month" column from the first table:

Store    Jan-2020    Feb-2020    Mar-2020    Apr-2020
A        400         200         100         -
B        -           500         400         -
C        -           -           -           600

Is this possible?


Solution

  • Postgres does have a crosstab function, but I think using the built in filtering functionality is simple in this case:

    select store,
           sum(sales) filter (where month = 'Jan-2020') as Jan_2020,
           sum(sales) filter (where month = 'Feb-2020') as Feb_2020,
           sum(sales) filter (where month = 'Mar-2020') as Mar_2020,
           sum(sales) filter (where month = 'Apr-2020') as Apr_2020
    from t
    group by store
    order by store;
    

    Note: This puts NULL values in the columns with no corresponding value, rather than -. If you really wanted a hyphen, you would need to convert the value to a string -- and that seems needlessly complicated.