Showing posts with label rotate. Show all posts
Showing posts with label rotate. Show all posts

Saturday, October 15, 2011

PostgreSQL crosstab query - Rotate a table about a pivot

An interesting feature of relational databases(postgres in this case) is the ability to rotate the table about a pivot. So if you have data like this-
 id | rowid | key | value
---+------+----+-------
  1 | test1 | key1      | val1
  2 | test1 | key2      | val2
  3 | test1 | key3      | val3
  4 | test1 | key4      | val4
  5 | test2 | key1      | val5
  6 | test2 | key2      | val6
  7 | test2 | key3      | val7
  8 | test2 | key4      | val8

And want to have a result set like this -

rowid | key1 | key2 | key3 | key4
------+------+-----+-----+------
 test1  | val1  | val2  | val3  | val4
 test2  | val5  | val6  | val7  | val8


It can be achieved by a "crosstab" query in a postgres database -

SELECT * FROM crosstab(
'SELECT rowid, key, value
FROM test WHERE key= ''key1'' OR key = ''key2''
OR key = ''key3'' OR key = ''key4''
ORDER BY 1,2') AS
ct(rowid text, key1 text, key2 text,
key3 text, key4 text);
view raw crosstab.sql hosted with ❤ by GitHub


Update: 02/14/2013
The following can be achieved by a crosstab and also by an interesting SQL which I came across here - http://stackoverflow.com/questions/14863985/postgres-crosstab-maybe
date | type | value
_________________________
2012-01-01 | 1 | 100
2012-01-01 | 2 | 200
2012-01-02 | 1 | 200
2012-01-02 | 2 | 300
2012-01-03 | 1 | 500
2012-01-03 | 2 | 10
view raw gistfile1.txt hosted with ❤ by GitHub
METHOD 1(faster):
select date,
sum(case when type = 1 then value end) Type1,
sum(case when type = 2 then value end) Type2
from yourtable
group by date
METHOD 2:
select * from crosstab('select date::text, type::text,
value::numeric(16,2) from tableA where
type in (1,2)
and date between ''2012-02-06'' and ''2013-02-13''
ORDER by 1,2' )
AS ct(date text,type1 numeric(16,2), type2 numeric(16,2))
view raw Crosstab.sql hosted with ❤ by GitHub