我在 Postgresql 9.6.5 中有一个表,其中包含一些字段,例如:
CREATE TABLE test (
id SERIAL,
data JSONB,
amount DOUBLE PRECESION,
PRIMARY KEY(id)
);
在data
列中有像这样的json对象:
{
"Type": 1,
"CheckClose":
{"Payments":
[
{"Type": 4, "Amount": 2068.07},
{"Type": 1, "Amount": 1421.07}
]
}
}
我需要做的是将Payments
字段的Amount
值的总和放入每行的amount
字段中 >数据
对象。例如,对于此特定对象,应为 2068.07 + 1421.07 = 3489.14。
我读过一些关于 Postgres json 和 jsonb 函数的内容,所以我现在在这里:
UPDATE test SET amount=sum((jsonb_array_elements(data::jsonb->'CheckClose'->'Payments')->>'Amount')::FLOAT)
这不起作用 - 我收到有关在 UPDATE 中未使用聚合函数的错误。
我尝试这样做:
UPDATE test SET amount=temp.sum
FROM (
SELECT sum((jsonb_array_elements(data::jsonb->'CheckClose'->'Payments')->>'Amount')::FLOAT) AS "sum"
FROM test WHERE id=test.id
) as "temp"
现在我收到错误在上下文中调用的集值函数无法接受集合
我应该怎么做?我只需要计算总和并将其放入另一行,这是一项艰巨的任务吗? 请任何人帮我解决这个问题。谢谢。
最佳答案
返回 fn() 聚合的集合尝试:
t=# with c(j) as (values('{"Payments":
[
{"Type": 4, "Amount": 2068.07},
{"Type": 1, "Amount": 1421.07}
]
}'::jsonb))
select sum((jsonb_array_elements(j->'Payments')->>'Amount')::float) from c;
错误:
ERROR: aggregate function calls cannot contain set-returning function calls LINE 7: select sum((jsonb_array_elements(j->'Payments')->>'Amount'):... ^ HINT: You might be able to move the set-returning function into a LATERAL FROM item.
很容易被另一个 cte 克服:
t=# with c(j) as (values('{"Payments":
[
{"Type": 4, "Amount": 2068.07},
{"Type": 1, "Amount": 1421.07}
]
}'::jsonb))
, a as (select (jsonb_array_elements(j->'Payments')->>'Amount')::float am from c)
select sum(am) from a;
sum
---------
3489.14
(1 row)
所以现在只需从 CTE 更新:
with s as (SELECT ((jsonb_array_elements(data::jsonb->'CheckClose'->'Payments')->>'Amount')::FLOAT) AS "sm", id
FROM test
)
, a as (select sum(sm), id from s group by id)
UPDATE test SET amount = sum
FROM a
WHERE id=test.id
关于sql - Postgresql根据其JSONB字段值总和更新记录列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48209368/