poStrgesQL:从JSONB值的嵌套数组字段编辑特定字段

发布于 2025-01-20 21:34:12 字数 1391 浏览 3 评论 0原文

表:

table Bar(
  id int,
  my_json jsonb
)

my_json的示例:

{
  "foo": "bar",
  "columns": [
    {
      "type": "integer",
      "field": "myField",
      "children": [
        {
          "type": "integer",
          "field": "myField"
        }
      ]
    },
    {
      "type": "integer",
      "field": "otherField",
      "children": [
        {
          "type": "integer",
          "field": "myField"
        }
      ]
    },
    {
      "type": "integer",
      "field": "baz",
      "children": null
    }
  ]
}

我需要更改所有“ type”:“ integer” “ type” type“:“ string” 匹配<代码>“字段”等于“ myfield”

我使用此下一个SQL查询制作了LVL 1(在 lvl):

with query as (
    select ('{columns,' || index - 1 || ',type}')::text[] as path,
           b.id
    from Bar b,
         jsonb_array_elements(my_json -> 'columns') with ordinality arr(col, index)
    where col ->> 'field' = 'myField'
      and col ->> 'type' = 'integer'
)
update Bar b
set my_json = jsonb_set(b.my_json, query.path, '"string"', false)
from query
where b.id = query.id;

我必须使用Nested Array 可以实现LVL 2(理想地了解任何LVL)保持无效,我不知道该怎么做。

The table:

table Bar(
  id int,
  my_json jsonb
)

Example of what my_json looks like:

{
  "foo": "bar",
  "columns": [
    {
      "type": "integer",
      "field": "myField",
      "children": [
        {
          "type": "integer",
          "field": "myField"
        }
      ]
    },
    {
      "type": "integer",
      "field": "otherField",
      "children": [
        {
          "type": "integer",
          "field": "myField"
        }
      ]
    },
    {
      "type": "integer",
      "field": "baz",
      "children": null
    }
  ]
}

I need to change all the "type": "integer" to "type": "string" where the matching "field" equals to "myField".

I made the lvl 1 (at columns lvl) with this next sql query:

with query as (
    select ('{columns,' || index - 1 || ',type}')::text[] as path,
           b.id
    from Bar b,
         jsonb_array_elements(my_json -> 'columns') with ordinality arr(col, index)
    where col ->> 'field' = 'myField'
      and col ->> 'type' = 'integer'
)
update Bar b
set my_json = jsonb_set(b.my_json, query.path, '"string"', false)
from query
where b.id = query.id;

I have to achieve the lvl 2 (ideally understand any lvl) with the nested array children which may be null, and I don't know how to do it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

━╋う一瞬間旳綻放 2025-01-27 21:34:12

我做到了!这是我发现的解决方案:

with non_null_children as (
    select index - 1 as idx,
           col,
           b.id as bar_id
    from Bar b,
         jsonb_array_elements(my_json -> 'columns') with ordinality arr(col, index)
    where col ->> 'children' is not null
), query as (
    select ('{columns,' || nnc.idx || ',children,' || index - 1 || ',type}')::text[] as path,
           b.id
    from Bar b,
         non_null_children nnc,
         jsonb_array_elements(nnc.col -> 'children') with ordinality arr(col2, index)
    where b.id = nnc.bar_id
      and col2 ->> 'field' = 'myField'
      and col2 ->> 'type' = 'integer'
)
update Bar b
set my_json = jsonb_set(b.my_json, query.path, '"string"', false)
from query
where b.id = query.id;

说明:

  • 我列出了所有包含孩子的项目,每个项目与索引及其bar ID - &gt; non_null_children < / code>
  • 对于每个bar ID /列索引,我可以像LVL 1一样在匹配的现场操作上工作。

我不知道这是否是最优化的解决方案,如果您认为这是必要的。

I made it! Here's the solution I found:

with non_null_children as (
    select index - 1 as idx,
           col,
           b.id as bar_id
    from Bar b,
         jsonb_array_elements(my_json -> 'columns') with ordinality arr(col, index)
    where col ->> 'children' is not null
), query as (
    select ('{columns,' || nnc.idx || ',children,' || index - 1 || ',type}')::text[] as path,
           b.id
    from Bar b,
         non_null_children nnc,
         jsonb_array_elements(nnc.col -> 'children') with ordinality arr(col2, index)
    where b.id = nnc.bar_id
      and col2 ->> 'field' = 'myField'
      and col2 ->> 'type' = 'integer'
)
update Bar b
set my_json = jsonb_set(b.my_json, query.path, '"string"', false)
from query
where b.id = query.id;

Explanation:

  • I list all the items which contain children, each combined with its columns index and its Bar id -> non_null_children
  • For each Bar id / column index, I can work on the matching field operation, just like the lvl 1.

I don't know if this is the most optimized solution, feel free to improve it if you think it's necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文