2013-01-21 71 views
0

我有去有这样的列的查询......PostgreSQL的查询,返回一个列JSON /名称值对的/ etc

systemid | created | updated 

每个系统ID有name值的任意集配对在一张看起来像这样的表格中。

systemid | name | value 

所以这个表可能有

1,'name','ben' 
1,'age',42 
2,'name','john' 
2,'age',22 
2,'favoritecolor','red' 

有谁知道的方法,使查询返回的所有名称值对一个SYSTEMID作为名称/值对类型?我想得到这样的结果。

systemid | created | updated | profiledata 

1,'name','ben','jan 1, 2012, 'name=>\'ben\',age=42' 
2,'name','john','sept 15, 2011, 'name=>\'john\',age=22, favoritecolor=>\'red\'' 

回答

1

我想你可以沿着这些线路试一下:

postgres=# CREATE TABLE attr(systemid int, name varchar(32), value varchar(64)); 
CREATE TABLE 
postgres=# 
postgres=# INSERT INTO attr VALUES(1,'name','ben'); 
INSERT 0 1 
postgres=# INSERT INTO attr VALUES(1,'age', '42'); 
INSERT 0 1 
postgres=# INSERT INTO attr VALUES(2,'name','john'); 
INSERT 0 1 
postgres=# INSERT INTO attr VALUES(2,'age', '22'); 
INSERT 0 1 
postgres=# INSERT INTO attr VALUES(2,'favoritecolor','red'); 
INSERT 0 1 
postgres=# 
postgres=# SELECT systemid 
postgres-#  ,array_agg(name || '=' || value) AS profile_data 
postgres-# FROM attr 
postgres-# GROUP BY systemid; 
systemid |    profile_data 
----------+-------------------------------------- 
     1 | {name=ben,age=42} 
     2 | {name=john,age=22,favoritecolor=red} 
(2 rows) 

或者你可以看看hstore或JSON数据类型。

+0

我第二@ Glenn的想法是查看HStore和/或[JSON](http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.2#JSON_datatype)数据类型,特别是如果您说,名称值对是任意的。我和HStore一起工作过,很简单。 – iain

0

任何解决方案,这是大致将具有下列形式之一:

SELECT table1.systemid, 
     created, 
     updated, 
     some_aggregate_function(name, value) AS profiledata 
FROM table1 JOIN table2 ON table1.systemid = table2.systemid 
GROUP BY table1.systemid, created, updated 

SELECT table1.systemid, 
     created, 
     updated, 
     some_aggregate_function(some_function(name, value)) AS profiledata 
FROM table1 JOIN table2 ON table1.systemid = table2.systemid 
GROUP BY table1.systemid, created, updated 

这里是第二种方法,它作为返回的一个相当哈克,难看示例第四列带有名称/值对的JSON对象:

SELECT table1.systemid, 
     created, 
     updated, 
     '{' || array_to_string(
     array_agg(
      '"' || name || '":"' || value || '"' 
     ), ',' 
     ) || '}' AS profiledata 
FROM table1 
JOIN table2 
ON table1.systemid = table2.systemid 
GROUP BY table1.systemid, created, updated; 

如果您想要更漂亮达到相同的结果,你可能想看看defining your own aggregate functions。恐怕我没有任何一种SQL专家,所以我不能在头脑中想出一个漂亮,优雅的解决方案,但希望这会让你走上正轨。