将另一个 key/value 对添加到 POSTGRES 中 jsonb 数组内的所有对象
Add another key/value pair to all objects inside a jsonb array in POSTGRES
我有一个table,我们称它为myTable,结构如下
ID | data
____________
uuid | jsonb
jsonb字段中的数据是一个结构如下的数组:
[
{
"valueA": "500",
"valueB": "ABC",
},
{
"valueA": "300",
"valueB": "CDE",
}
]
我想要做的是通过添加一个 valueC 来转换该数据并将其设置为 valueA,对于 'data' jsonb 数组中的所有对象。
这是我想要的结果:
[
{
"valueA": "500",
"valueB": "ABC",
"valueC": "500",
},
{
"valueA": "300",
"valueB": "CDE",
"valueC": "300",
}
]
我尝试使用以下查询进行操作:
UPDATE myTable
SET data = d.json_array
FROM (
SELECT
jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
) as json_array
FROM
myTable,
jsonb_array_elements(data) elems
) d;
这对 myTable 中的某些条目有效,但对某些人来说它变得疯狂并创建了 300 多个额外的条目,以及我以前拥有的条目。
我在查询中遗漏了什么?
那些FROM
语句是不必要的。您根本不需要 UPDATE
子句 - 您的问题是子查询执行 FROM myTable
然后基本上 self-joins (按笛卡尔积)此子查询结果针对整个 myTable
。每行的最后一个(或任何一个)UPDATE
获胜,具体取决于连接顺序,使您的结果不可预测table.
我将移动 SET
子句中的子查询,它只引用正在更新的行的 data
:
UPDATE myTable
SET data = (
SELECT jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
)
FROM jsonb_array_elements(data) elems
);
或者,您需要在更新的 table 和 FROM
结果之间添加 JOIN 条件:
UPDATE myTable u
SET data = d.json_array
FROM (
SELECT
id,
jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
) as json_array
FROM
myTable,
jsonb_array_elements(data) elems
GROUP BY
id
) d
WHERE
u.id = d.id;
我有一个table,我们称它为myTable,结构如下
ID | data
____________
uuid | jsonb
jsonb字段中的数据是一个结构如下的数组:
[
{
"valueA": "500",
"valueB": "ABC",
},
{
"valueA": "300",
"valueB": "CDE",
}
]
我想要做的是通过添加一个 valueC 来转换该数据并将其设置为 valueA,对于 'data' jsonb 数组中的所有对象。
这是我想要的结果:
[
{
"valueA": "500",
"valueB": "ABC",
"valueC": "500",
},
{
"valueA": "300",
"valueB": "CDE",
"valueC": "300",
}
]
我尝试使用以下查询进行操作:
UPDATE myTable
SET data = d.json_array
FROM (
SELECT
jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
) as json_array
FROM
myTable,
jsonb_array_elements(data) elems
) d;
这对 myTable 中的某些条目有效,但对某些人来说它变得疯狂并创建了 300 多个额外的条目,以及我以前拥有的条目。
我在查询中遗漏了什么?
那些FROM
语句是不必要的。您根本不需要 UPDATE
子句 - 您的问题是子查询执行 FROM myTable
然后基本上 self-joins (按笛卡尔积)此子查询结果针对整个 myTable
。每行的最后一个(或任何一个)UPDATE
获胜,具体取决于连接顺序,使您的结果不可预测table.
我将移动 SET
子句中的子查询,它只引用正在更新的行的 data
:
UPDATE myTable
SET data = (
SELECT jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
)
FROM jsonb_array_elements(data) elems
);
或者,您需要在更新的 table 和 FROM
结果之间添加 JOIN 条件:
UPDATE myTable u
SET data = d.json_array
FROM (
SELECT
id,
jsonb_agg(
jsonb_set(elems, '{valueC}', elems->'valueA')
) as json_array
FROM
myTable,
jsonb_array_elements(data) elems
GROUP BY
id
) d
WHERE
u.id = d.id;