0

我有一个查询有这样的列......

systemid | created | updated

对于每个系统 ID,表中都有一组任意名称值对,如下所示。

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\''
4

2 回答 2

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 数据类型。

于 2013-01-22T00:26:04.877 回答
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

这是第二种方法的一个相当hacky,丑陋的例子,它作为第四列返回一个带有名称/值对的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;

如果您想要更漂亮的东西来获得相同的结果,您可能需要考虑定义自己的聚合函数。恐怕我不是任何一种 SQL 高手,所以我无法想出一个好的、优雅的解决方案,但希望这能让你走上正轨。

于 2013-01-22T00:34:43.987 回答