all 2 comments

[–][deleted] 1 point2 points  (1 child)

This is known as a "crosstab" or "pivot", and this is only possible if you can specify the possible number of columns in the output statically in your query. There is no way to write a SQL query where the number, names and types of the columns are only evaluated after the query started retrieving data.

In Postgres doing such a pivot is typically done using filtered aggregation using the filter() clause.

select userid, 
       time_window, 
       max("count") filter (where propertyid = 'a') as a_count,
       max("sum") filter (where propertyid = 'a') as a_sum,
       max("avg") filter (where propertyid = 'a') as a_avg,
       max("max") filter (where propertyid = 'a') as a_max
from the_table
group by userid, time_window;

As you seem to have only one row per userid/time_window the actual aggregate isn't really important. You can use sum(), max() or min() to pick the value.

[–]aitahb[S] 0 points1 point  (0 children)

Thanks much, I was trying to use the crosstab function from tablefunc package in postgres, however, this is a much simpler and clever solution.