次の表があります。
roles
id | name | person
---+-------+--------
1 | admin | jon
2 | admin | fred
3 | user | alfred
4 | user | jon
名前は任意の値に変更できます。
次のような JSON ハッシュを取得したいと思います。
{"admin": ["jon", "fred"], "user": ["alfred", "jon"]}
PL/PGSQL の使用
次の表があります。
roles
id | name | person
---+-------+--------
1 | admin | jon
2 | admin | fred
3 | user | alfred
4 | user | jon
名前は任意の値に変更できます。
次のような JSON ハッシュを取得したいと思います。
{"admin": ["jon", "fred"], "user": ["alfred", "jon"]}
PL/PGSQL の使用
The current development version - future 9.3 - of postgres will put a strong focus on JSON support inside the database. Depending on how fast you need a solution for this problem you could wait for 9.3 or install the current beta (which should include the new features).
Here are two articles regarding the new json features - first is third party - second is the JSON lib reference on the dev tree:
名前はさまざまな原因で変わる可能性があると思いますが、それは問題ではありません。eval関数を使用します。
CREATE OR REPLACE FUNCTION eval(expression text) RETURNS text
AS
$body$
DECLARE
result text;
BEGIN
execute expression INTO RESULT;
RETURN result;
END;
$body$
language plpgsql
動的クロス集計を作成できます。
SELECT eval('SELECT row_to_json(q)
FROM (SELECT '||(SELECT string_agg(DISTINCT '"'||name||'"',',')
FROM roles)||'
FROM crosstab(''SELECT 1,name,array_agg(person)::text[]
FROM roles
GROUP BY name;
'') as ct(row_name int,'||(SELECT string_agg(DISTINCT '"'||name||'" text[]',',')
FROM roles)||')
)as q');
派手でないアプローチ:
SELECT '{'||string_agg(temp,',')||'}'
FROM
(
SELECT '"'||name||'": ['||(string_agg(person,',')::text)||']' as temp FROM roles GROUP BY name
) as q