PostgreSQL - 用于JSONB列的GROUP_CONCAT

时间:2017-06-21 14:34:39

标签: postgresql aggregate group-concat jsonb

我尝试使用Postgres找到一种连接JSONB值的方法。

例如我有两行:

INSERT INTO "testConcat" ("id", "json_data", "groupID") 
VALUES (1, {"name": "JSON_name1", "value" : "Toto"}, 5);

INSERT INTO "testConcat" ("id", "json_data", "groupID") 
VALUES (2, {"name": "JSON_name2"}, 5);

我想做点什么:

SELECT GROUP_CONCAT(json_data)
FROM testConcat
GROUP BY groupID

以结果获得如下结果:

[{"name": "JSON_name1", "value": "Toto"}, {"name": "JSON_name2"}]

我尝试创建聚合函数,但是当JSON中存在相同的键时,它们会被合并,只保留最后的值:

DROP AGGREGATE IF EXISTS jsonb_merge(jsonb);

CREATE AGGREGATE jsonb_merge(jsonb) (
    SFUNC = jsonb_concat(jsonb, jsonb),
    STYPE = jsonb,
    INITCOND = '{}'
 );

当我在这里使用此功能时:

SELECT jsonb_merge(json_data)
FROM testConcat
GROUP BY groupID

结果是:

{"name": "JSON_name2", "value": "Toto"}

而不是那些我想要的因为

{"name": "JSON_name1"}

缺少。该函数仅保留不同的键,并将另一个键与最后一个值合并。

感谢您的帮助

2 个答案:

答案 0 :(得分:4)

如果JSON文档中始终只有一个键/值对,则可以在没有自定义聚合函数的情况下执行此操作:

SELECT groupid, jsonb_object_agg(k,v order by id)
FROM testconcat, jsonb_each(json_data) as x(k,v)
group by groupid;

" last"值由id

上的排序定义

自定义聚合函数可能会更快。

答案 1 :(得分:1)

最后我找到了一个解决方案,即使它不是最好的,它似乎也有效。

我创建了agreate函数,如前所述,稍作修改:

set JAVA_OPTS=%JAVA_OPTS% -Djuli-logback.configurationFile="%CATALINA_HOME%\conf\logback.xml"

我只是替换:

DROP AGGREGATE IF EXISTS jsonb_merge(jsonb);

CREATE AGGREGATE jsonb_merge(jsonb) (
   SFUNC = jsonb_concat(jsonb, jsonb),
   STYPE = jsonb,
   INITCOND = '[]'
);

INITCOND = '{}'

之后使用它:

INITCOND = '[]'