5

How can I unpivot in Postgresql without using UNION? I have more than 100 columns, and I am looking for a neat way to do it.

Given table:

id    c1      c2      c3
1      X       Y       Z
2      A       B       C
3      Y       C       Z

Desired table:

id   col
1     X
1     Y
1     Z
2     A
2     B
2     C
3     Y
3     C
3     Z
geek2000
  • 451
  • 5
  • 18

1 Answers1

5

Use jsonb functions:

select id, value as col
from my_table
cross join jsonb_each_text(to_jsonb(my_table))
where key <> 'id';

 id | value 
----+-------
  1 | X
  1 | Y
  1 | Z
  2 | A
  2 | B
  2 | C
  3 | Y
  3 | C
  3 | Z
(9 rows)

Db<>Fiddle.


In Postgres 9.3 or 9.4 use to_json() and json_each_text().

In versions 9.1 or 9.2 install hstore:

create extension if not exists hstore;

select id, value as col
from my_table
cross join each(hstore(my_table))
where key <> 'id';
klin
  • 112,967
  • 15
  • 204
  • 232
  • Thank you @klin. I am getting the following error: function to_jsonb(my_table) does not exist. Do you have any idea why this is happening? – geek2000 Aug 30 '17 at 01:28
  • The function is available in Postgres 9.5+; if you have version 9.3 or 9.4 use `json_each_text()` and `to_json()`. – klin Aug 30 '17 at 01:41
  • Thanks but getting the same error. Can it be that my postgres installation missing something? – geek2000 Aug 30 '17 at 01:46
  • What is your Postgres version? – klin Aug 30 '17 at 01:46
  • It is 9.2. Probably that's why! – geek2000 Aug 30 '17 at 01:48
  • Yes, unfortunately, in 9.2 json type support is residual. Upgrade! ;) – klin Aug 30 '17 at 01:50
  • Oops! :) Thanks. Marked as right answer. I am pretty sure this is the correct answer if I had the correct version! :) – geek2000 Aug 30 '17 at 01:51
  • It seems I should either upgrade or use UNION! :) hstore didn't work either. throwing: function expression in FROM cannot refer to other relations of same query level... it complains about "my_table" in hstore(my_table). – geek2000 Aug 30 '17 at 02:18