I have a table that looks like this:
id feh bar
1 10 A
2 20 A
3 3 B
4 4 B
5 5 C
6 6 D
7 7
This is to complete @Damian good answer. I have already suggested the JSON approach in other answers before the 9.6's handy json_object_agg
function. It just takes more work with the previous tool set.
Two of the cited possible drawbacks are really not. The random key order is trivially corrected if necessary. The missing keys, if relevant, takes an almost trivial amount of code to be addressed:
select
row_name as bar,
json_object_agg(attrib, val order by attrib) as data
from
tbl
right join
(
(select distinct row_name from tbl) a
cross join
(select distinct attrib from tbl) b
) c using (row_name, attrib)
group by row_name
order by row_name
;
bar | data
-----+----------------------------------------------
a | { "val1" : 10, "val2" : 20, "val3" : null }
b | { "val1" : 3, "val2" : 4, "val3" : null }
c | { "val1" : 5, "val2" : null, "val3" : null }
d | { "val1" : 6, "val2" : 7, "val3" : 8 }
For a final query consumer which understands JSON there are no drawbacks. The only one is that it can not be consumed as a table source.