PostgreSQL 按行聚合 JSON 个记录集键
PostgreSQL aggregate JSON recordset keys by row
我将 PostgreSQL table 中每一行的数据存储在 JSON 数组中,如下所示:
id data
-------------------------------------------------
1 [{"a": 1, "b": 2}, {"a": 3, "b":2}]
2 [{"a": 5, "b": 8}, {"a": 9, "b":0}]
如何获取按 id 分组的记录集中特定键的总和?
这是所需结果集的示例:
id a b
-------------------------------------------------
1 4 4
2 14 8
更新:
我还应该提到数据列是 jsonb 数据类型。
这是我第一次使用 Postgres 的新 JSON 函数,它们非常简洁!我使用名为 test
的 table 获得此解决方案。
我拆分数组元素,然后将它们扩展为 key/value 对,然后在外部查询中对它们求和。
我不得不做一个讨厌的双重转换 ::text::integer
来获得 JSON 值作为整数,因为你不能从 JSON 直接转换为整数,正如我在 this answer.
我找到了如何拆分 key/value 元组 in this tutorial。
SELECT id,
SUM(CASE WHEN k = 'a' THEN v ELSE 0 END) AS a,
SUM(CASE WHEN k = 'b' THEN v ELSE 0 END) AS b
FROM (
SELECT id,
(json_each(json_array_elements(data))).key as k,
(json_each(json_array_elements(data))).value::text::integer AS v FROM test
) AS json_data
GROUP BY id
给出结果:
id | a | b
-----------
1 | 4 | 4
2 | 14 | 8
select id, sum(a), sum(b)
from jsontable j
CROSS JOIN LATERAL
json_to_recordset(j.data) as x(a integer, b integer)
group by id
在这里您可以测试查询或 fiddle 用它 http://rextester.com/ZTCY82930
有关 json_to_recordset 的文档,请参阅此 https://www.postgresql.org/docs/9.6/static/functions-json.html
编辑: 正如您在更新中所说,您使用了一个 jsonb 字段,所以不要使用 json_to_recordset
,只需使用 jsonb_to_recordset
我将 PostgreSQL table 中每一行的数据存储在 JSON 数组中,如下所示:
id data
-------------------------------------------------
1 [{"a": 1, "b": 2}, {"a": 3, "b":2}]
2 [{"a": 5, "b": 8}, {"a": 9, "b":0}]
如何获取按 id 分组的记录集中特定键的总和? 这是所需结果集的示例:
id a b
-------------------------------------------------
1 4 4
2 14 8
更新:
我还应该提到数据列是 jsonb 数据类型。
这是我第一次使用 Postgres 的新 JSON 函数,它们非常简洁!我使用名为 test
的 table 获得此解决方案。
我拆分数组元素,然后将它们扩展为 key/value 对,然后在外部查询中对它们求和。
我不得不做一个讨厌的双重转换 ::text::integer
来获得 JSON 值作为整数,因为你不能从 JSON 直接转换为整数,正如我在 this answer.
我找到了如何拆分 key/value 元组 in this tutorial。
SELECT id,
SUM(CASE WHEN k = 'a' THEN v ELSE 0 END) AS a,
SUM(CASE WHEN k = 'b' THEN v ELSE 0 END) AS b
FROM (
SELECT id,
(json_each(json_array_elements(data))).key as k,
(json_each(json_array_elements(data))).value::text::integer AS v FROM test
) AS json_data
GROUP BY id
给出结果:
id | a | b
-----------
1 | 4 | 4
2 | 14 | 8
select id, sum(a), sum(b)
from jsontable j
CROSS JOIN LATERAL
json_to_recordset(j.data) as x(a integer, b integer)
group by id
在这里您可以测试查询或 fiddle 用它 http://rextester.com/ZTCY82930
有关 json_to_recordset 的文档,请参阅此 https://www.postgresql.org/docs/9.6/static/functions-json.html
编辑: 正如您在更新中所说,您使用了一个 jsonb 字段,所以不要使用 json_to_recordset
,只需使用 jsonb_to_recordset