gpt4 book ai didi

sql - 如何根据对象 ID 将 jsonb 数组展开为每个 jsonb 列的对象?

转载 作者:行者123 更新时间:2023-11-29 13:18:09 27 4
gpt4 key购买 nike

给定类似于以下的现有数据结构:

CREATE TEMP TABLE sample (id int, metadata_array jsonb, text_id_one jsonb, text_id_two jsonb);
INSERT INTO sample
VALUES ('1', '[{"id": "textIdOne", "data": "foo"},{"id": "textIdTwo", "data": "bar"}]'), ('2', '[{"id": "textIdOne", "data": "baz"},{"id": "textIdTwo", "data": "fiz"}]');

我正在尝试将现有 元数据 列中的 jsonb 对象数组展开到同一表中的新 jsonb 列中;我已经根据已知的固定 ID 键列表创建了 textIdOnetextIdTwo

我以为我已经接近使用 jsonb_populate_recordset() 但后来意识到将根据所有 jsonb 对象的键填充列;不是我想要的。期望的结果是基于对象 ID 的每列对象。

此操作的另一个棘手部分是我的 JSON 对象的 id 值使用 camelCase 并且似乎应该避免使用引号/大小写的列名称,但我没有不介意引用或修改列名作为结束的手段 & 一旦更新查询完成,我可以根据需要手动更改列名。

我正在使用 PostgreSQL 9.5.2

现有数据和结构:

id | metadata_array jsonb                             | text_id_one jsonb | text_id_two jsonb
---------------------------------------------------------------------------------------------
1 | [{"id": "textIdOne"...}, {"id": "textIdTwo"...}] | NULL | NULL
2 | [{"id": "textIdOne"...}, {"id": "textIdTwo"...}] | NULL | NULL

期望的结果:

id | metadata_array jsonb     | text_id_one jsonb      | text_id_two jsonb
-------------------------------------------------------------------------------
1 | [{"id": "textIdOne",... | {"id": "textIdOne"...} | {"id": "textIdTwo"...}
2 | [{"id": "textIdOne",... | {"id": "textIdOne"...} | {"id": "textIdTwo"...}

说明:

感谢大家到目前为止的回答!虽然我知道完整的键列表(大约 9 个),但我不能指望顺序是一致的。

最佳答案

如果所有 json 数组都包含两个新列的两个元素,则使用 dmfay 的答案中的固定路径。否则你应该使用 jsonb_array_elements() 取消嵌套数组两次,分别用于 text_id_onetext_id_two

update sample t set
text_id_one = value1,
text_id_two = value2
from sample s,
jsonb_array_elements(s.metadata_array) as e1(value1),
jsonb_array_elements(s.metadata_array) as e2(value2)
where s.id = t.id
and value1->>'id' = 'textIdOne'
and value2->>'id' = 'textIdTwo'
returning t.*

Test the query in SqlFiddle.

如果数组的元素超过两个,这个变体可能更有效(也更方便):

update sample t
set
text_id_one = arr1->0,
text_id_two = arr2->0
from (
select
id,
jsonb_agg(value) filter (where value->>'id' = 'textIdOne') as arr1,
jsonb_agg(value) filter (where value->>'id' = 'textIdTwo') as arr2
from sample,
jsonb_array_elements(metadata_array)
group by id
) s
where t.id = s.id
returning t.*

SqlFiddle.

关于sql - 如何根据对象 ID 将 jsonb 数组展开为每个 jsonb 列的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46105430/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com