postgresqlgroup-bysumpivotpostgres-crosstab

Pivoting while grouping in postgres


I've been using crosstab in postgres to pivot a table, but am now needing to add in a grouping and I'm not sure if that's possible.

I'm starting with results like this:

Date          Account#    Type   Count  
-----------------------------------------
2020/1/1         100      Red       5   
2020/1/1         100      Blue      3   
2020/1/1         100      Yellow    7
2020/1/2         100      Red       2 
2020/1/2         100      Yellow    9  
2020/1/1         101      Red       4   
2020/1/1         101      Blue      7   
2020/1/1         101      Yellow    3
2020/1/2         101      Red       8
2020/1/2         101      Blue      6 
2020/1/2         101      Yellow    4       

And I'd like to pivot it like this, where there's a row for each combination of date and account #:

Date          Account#    Red   Blue  Yellow  
---------------------------------------------
2020/1/1         100      5       3     7   
2020/1/2         100      2       0     9   
2020/1/1         101      4       7     3
2020/1/2         101      8       6     4 
      

This is the code I've written returns the error "The provided SQL must return 3 columns: rowid, category, and values" which makes sense per my understanding of crosstab.

SELECT * 
FROM crosstab(
SELECT date, account_number, type, count
FROM table
ORDER BY 2,1,3'
) AS ct (date timestamp, account_number varchar, Red bigint, Blue bigint, Yellow bigint);

(I wrote the dates in a simplified format in the example tables but they are timestamps)

Is there a different way I can manipulate the first table to look like the second? Thank you!


Solution

  • You can do conditional aggregation:

    select
        date,
        account#,
        sum(cnt) filter(where type = 'Red'   ) red,
        sum(cnt) filter(where type = 'Blue'  ) blue,
        sum(cnt) filter(where type = 'Yellow') yellow
    from mytable
    group by date, account#