当前位置: 首页 > 面试题库 >

使用jsonb_set()进行条件更新

宋运锋
2023-03-14
问题内容

我在Postgres 11.3数据库中有一个带有jsonb列的表。

尝试更新嵌套数组名称中的所有对象"iProps"

如果路径{iProps -> value -> rules -> ao -> sc}是对象,则应将路径从对象更新为具有以下值的字符串: {iProps -> value -> rules -> ao -> sc -> name}

如果{iProps -> value -> rules -> ao -> sc}不存在该路径,则该对象应保持不变。

使用查询测试设置:小提琴链接

所需结果:

{
    "iProps": [
        {
            "value": {
                "rules": [
                    {
                        "ao": {
                            "set": "get"
                        },
                        "name": "PRule"
                    },
                    {
                        "ao": {
                            "sc":  "name1"

                        }
                    },
                    {
                        "ao": {
                            "sc": "name2"

                        }
                    },
                    {
                        "ao": {
                            "sc":  "name3"                            
                        }
                    }
                ]
            }
        }
    ]
}

我已经修改了查询并链接到小提琴中。有人可以看看是否正确吗?


问题答案:

平原CASE应该有所作为。

UPDATE table_ t
SET    value_ = jsonb_set(value_, '{iProps}', sub2.new_prop, false)
FROM  (
   SELECT id
        , jsonb_agg(jsonb_set(prop, '{value, rules}', new_rules, false)
                    ORDER BY idx1) AS new_prop
   FROM  (
      SELECT t.id, arr1.prop, arr1.idx1
           , jsonb_agg( **CASE WHEN jsonb_typeof(rule # > '{ao,sc}') = 'object'
                            THEN jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
                            ELSE rule
                       END**
                       ORDER BY idx2) AS new_rules
      FROM table_ t
         , jsonb_array_elements(value_->'iProps')       WITH ORDINALITY arr1(prop,idx1)
         , jsonb_array_elements(prop->'value'->'rules') WITH ORDINALITY arr2(rule,idx2)
      GROUP  BY t.id, arr1.prop, arr1.idx1
      ) sub1
   GROUP  BY id
   ) sub2
WHERE t.id = sub2.id;

db
<>在这里

拨弄 (Postgres 11!)

为了同时满足您在更新中添加的第二个过滤器(必须是一个 对象
),请使用进行检查jsonb_typeof()

小提琴中的查询似乎不必要地复杂(tl;
dr)。同样,它不保留 数组元素的原始顺序 。如果实际上不相关,请省略WITH ORDINALITYORDER BY进一步简化:

UPDATE table_ t
SET    value_ = jsonb_set(value_, '{iProps}', sub2.new_prop, false)
FROM  (
   SELECT id
        , jsonb_agg(jsonb_set(prop, '{value, rules}', new_rules, false)) AS new_prop
   FROM  (
      SELECT t.id, prop
           , jsonb_agg(CASE WHEN jsonb_typeof(rule #> '{ao,sc}') = 'object'
                            THEN jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
                            ELSE rule
                       END) AS new_rules
      FROM table_ t
         , jsonb_array_elements(value_->'iProps')       prop
         , jsonb_array_elements(prop->'value'->'rules') rule
      GROUP  BY t.id, prop
      ) sub1
   GROUP  BY id
   ) sub2
WHERE t.id = sub2.id;

db
<>在这里拨弄

通常,这仍会保留数组元素的顺序(与原始数组不同)。不能保证具有两个聚合级别。



 类似资料:
  • 问题内容: 使用in 时可以执行更新吗?例如: 问题答案: 有一个非常强大的功能,称为: [15.4。DML风格的操作](http://docs.jboss.org/hibernate/orm/4.3/manual/en- US/html/ch15.html#batch-direct) 来自doc的小引用: …但是,Hibernate提供了通过Hibernate查询语言执行批量SQL样式DML语句

  • 问题内容: 我正在尝试运行一个更新查询,它将在sql中看起来像这样: 我正在尝试使用 Criteria 这样重新创建查询: 这行不通,因为满足该条件的行很多,我的独特结果是我猜这里的问题。如何将其转换为符合条件的所有行的更新。我不想使用HQL查询,而是使用Criteria来执行。 问题答案: 始终建议执行批量操作非常接近数据库,除非需要,否则我们不需要在会话中保留更新的对象,因此,在执行批量操作时

  • 问题内容: 有没有办法在Redis中进行条件设置? 我想使用Redis缓存一些对象。缓存的每个用户(服务器程序)都将检查对象,并在对象具有更新版本时对其进行更新。我需要确保在更新步骤中,只有最新版本才真正保存在Redis中。 问题答案: 您可以编写一个lua脚本,该脚本将检查密钥的当前值,如果该值与新密钥不同,则将其更改。我在c中添加了一个通过c程序调用lua脚本的示例,并完成了所需的工作。

  • 问题内容: 我有一个不时更新数据集的数据库。在这里,可能发生的是交付了数据库中已经存在的数据集。 目前,我首先要做的是 检查是否已经存在具有这些数据的数据集(使用WHERE语句中的数据)。如果没有返回任何值,则说明我正在执行INSERT。 但这对我来说似乎有点复杂。所以我的问题是:是否有某种条件式INSERT仅在不存在新数据集的情况下才添加它? 我正在使用 SmallSQL 问题答案: 您几乎可以

  • 在一个有四列的大数据框(“myfile”)中,我必须添加第五列,其中的值有条件地基于前四列。 更喜欢使用和的答案,主要是因为它在大型数据集中的速度。 我的数据框如下所示: 第五列(V5)的值基于一些条件规则: 现在我想使用函数在所有行上使用这些规则(以避免慢循环)。类似这样的事情(是的,我知道这样不行!): 结果应该是: 如何在dplyr中执行此操作?

  • 我想使用条件查询。 这是我的问题 这是我的java代码 它给出