从Postgres中的2个聚合列构建JSON

时间:2016-10-07 16:49:34

标签: json postgresql aggregate aggregate-functions jsonb

使用Postgres-Db作为json文档的源代码,我需要将表中的两列转换为JSON对象。

所以我在颜色表中有“color_id”,“language”和“name”列:

    color_id |   language  | name
    1        |      "de"   |  "blau"
    1        |      "en"   |  "blue"
    1        |      "fr"   |  "bleu"

我想生成一个JSON对象,如:

    {
      "de": "blau",
      "fr": "bleu",
      "en": "blue"
    }

我从

开始
    SELECT
      array_to_json(array_agg((language::text, name::text))),
      color_id
    FROM colors
    GROUP BY color_id;

不幸生产

    array to json                 | color_id
    "[{"f1":"de","f2":"blau"}     |
      , {"f1":"en","f2":"blue"}   | 1
      , {"f1":"fr","f2":"bleu"}]" | 

我认为这很简单 - 或多或少 - 但发现自己处于误导性结果和语法错误的死胡同。

亲切的问候,多米尼克

2 个答案:

答案 0 :(得分:7)

使用jsonb_object_agg()

with data(color_id, language, name) as (
values
    (1, 'de', 'blau'),
    (1, 'en', 'blue'),
    (1, 'fr', 'bleu')
)
select color_id, jsonb_object_agg(language, name)
from data
group by 1;

 color_id |              jsonb_object_agg              
----------+--------------------------------------------
        1 | {"de": "blau", "en": "blue", "fr": "bleu"}
(1 row)

Postgres 9.5.

中引入了jsonb_object_agg()函数

在Postgres 9.4中使用json_object_agg()代替。

在Postgres 9.3中,你必须使用字符串函数构造结果:

select 
    color_id, 
    format('{%s}', string_agg(format('"%s": "%s"', language, name), ', '))::json
from data
group by 1;

答案 1 :(得分:1)

对于键值对和Proper JSON数据,可以使用

with data(color_id, language, name) as (
values
    (1, 'de', 'blau'),
    (1, 'en', 'blue'),
    (1, 'fr', 'bleu')
)
    SELECT color_id,
     json_agg((SELECT x FROM (SELECT language, name) AS x)) AS json_data
FROM data
group by "data".color_id;