2013-01-21 105 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專家,所以我不能在頭腦中想出一個漂亮,優雅的解決方案,但希望這會讓你走上正軌。