PostgreSQL - GROUP_CONCAT 用于 JSONB 列
PostgreSQL - GROUP_CONCAT for JSONB column
我试图找到一种使用 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
AND 作为获得类似结果的结果:
[{"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"}
丢失。该函数仅保留不同的键并将另一个键与最后一个值合并。
感谢您的帮助
最后我找到了一个解决方案,即使不是最好的,但似乎可行。
我创建了 agreate 函数,如前所述,稍作修改:
DROP AGGREGATE IF EXISTS jsonb_merge(jsonb);
CREATE AGGREGATE jsonb_merge(jsonb) (
SFUNC = jsonb_concat(jsonb, jsonb),
STYPE = jsonb,
INITCOND = '[]'
);
我只是替换:
INITCOND = '{}'
与
INITCOND = '[]'
和以前一样使用后:
SELECT jsonb_merge(json_data)
FROM testConcat
GROUP BY groupID
如果 JSON 文档中始终只有一个 key/value 对,您可以在没有自定义聚合函数的情况下执行此操作:
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
列上的顺序定义
不过,自定义聚合函数可能会更快。
我试图找到一种使用 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
AND 作为获得类似结果的结果:
[{"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"}
丢失。该函数仅保留不同的键并将另一个键与最后一个值合并。
感谢您的帮助
最后我找到了一个解决方案,即使不是最好的,但似乎可行。
我创建了 agreate 函数,如前所述,稍作修改:
DROP AGGREGATE IF EXISTS jsonb_merge(jsonb);
CREATE AGGREGATE jsonb_merge(jsonb) (
SFUNC = jsonb_concat(jsonb, jsonb),
STYPE = jsonb,
INITCOND = '[]'
);
我只是替换:
INITCOND = '{}'
与
INITCOND = '[]'
和以前一样使用后:
SELECT jsonb_merge(json_data)
FROM testConcat
GROUP BY groupID
如果 JSON 文档中始终只有一个 key/value 对,您可以在没有自定义聚合函数的情况下执行此操作:
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
列上的顺序定义
不过,自定义聚合函数可能会更快。