使用 jsonb_set() 有条件更新

2023-12-21

我在 Postgres 11.3 数据库中有一个表,其中包含jsonb column.

尝试更新嵌套数组名称内的所有对象"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"                            
                        }
                    }
                ]
            }
        }
    ]
}

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


A plain CASE https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-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;

数据库小提琴(Postgres 11!)

为了还满足您在更新中添加的第二个过滤器(必须是object),检查jsonb_typeof() https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE.

查询在似乎不必要地复杂(tl;dr)。此外,它不保留数组元素的原始顺序。如果这实际上无关紧要,请省略WITH ORDINALITY and ORDER 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;

数据库小提琴

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

See:

  • PostgreSQL unnest() 与元素编号 https://stackoverflow.com/questions/8760419/postgresql-unnest-with-element-number/8767450#8767450

我对您之前相关问题的回答中提供了更多建议:

  • 使用 jsonb_set() 进行更新仅影响嵌套数组中的一个对象 https://stackoverflow.com/questions/65799161/update-with-jsonb-set-only-affects-one-object-in-nested-array/65800790#65800790
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 jsonb_set() 有条件更新 的相关文章

  • Google Cloud SQL - Postgresql 存储不断增长

    我最近开始修补 Google Cloud SQL PostgreSQL 我创建了一个空数据库 在 4 5 天的时间里 其存储使用量已增长到超过 20GB 它一直在上升 但数据库中没有数据 它甚至没有被使用 有谁知道会发生什么以及如何阻止它
  • 更改迁移中的自动​​增量值(PostgreSQL 和 SQLite3)

    我有一个托管在 Heroku 上的项目 想要更改表的自动增量起始值 我在本地使用 SQLite3 Heroku 使用 PostgreSQL 这是我在迁移中所拥有的 class CreateMytable lt ActiveRecord Mi
  • Oracle:使用SQL或PL/SQL查找动态SQL中的错误位置

    如何在 PL SQL 或 SQL 中找到动态 SQL 语句中的错误位置 从 SQL Plus 中 我看到了错误的位置 例如 无效的 SQL DML 语句 SYS orcl gt SELECT 2 X 3 FROM 4 TABLEX 5 TA
  • 插入触发器最终在分区表中插入重复行

    我有一个分区表 我认为 适当的INSERT触发器和一些限制 不知何故 INSERT语句为每个语句插入 2 行INSERT 一个用于父分区 一个用于相应的分区 设置简要如下 CREATE TABLE foo id SERIAL NOT NUL
  • 列中差异的数量

    我想检索一列每行中有多少个字母的差异 例如 如果您有一个值 test 而另一行有一个值 testing 则 test 和 testing 之间的差异为 4 个字母 该列的数据值为 4 I have reflected about it an
  • sql server 按组排名

    问题看似简单 但我却无法理解 这是针对 sql 服务器的 what I have in a table What I need as a output cksum id cksum id 2162514679 204 2162514679
  • 了解 SSMS 2008 中关系的更新和删除规则

    当我们定义外键约束时 我对 SQL Server 2008 Management Studio 中的更新和删除规则的含义感到困惑 我也没有找到相关的帮助文档 例如F1帮助 这是屏幕快照 如果有人能描述它们的含义并推荐一些相关文档来阅读 我将
  • 如何从 PostgreSQL 中的时间戳列值提取一天中的时间(或小时)?

    我正在尝试从 PostgreSQL 中的 时间戳 列中提取一天中的时间 这是我的做法 但是 太糟糕了 知道如何做得更好吗 SELECT date part hour date demande text hours date part min
  • 对多个数据库执行 SQL 查询

    我知道我的帖子与该论坛中的其他帖子的标题非常相似 但我真的找不到我需要的答案 这是我的问题 我的 Windows Server 上运行着 SQL Server 在我的 SQL Server 中 我有大约 30 个数据库 它们都具有相同的表和
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样
  • PHP 通过 SSL 连接到 MS SQL

    我想要实现的目标非常简单 我想通过安全连接从 PHP 脚本连接到外部 MS SQL 数据库 然而 这已被证明是有问题的 到目前为止 经过三个小时的研究 我不知所措 客户端的平台是Ubuntu 这意味着我无法使用SQLSRV 安全连接已经在不
  • MySQL 查询到 CSV [重复]

    这个问题在这里已经有答案了 有没有一种简单的方法来运行MySQL查询来自linux命令行并以csv格式输出结果 这就是我现在正在做的事情 mysql u uid ppwd D dbname lt lt EOQ sed e s g tee l
  • SELECT 语句会受到 SQL 注入攻击吗?

    实际上有2个问题 我知道我必须尽可能多地使用存储过程 但我想知道以下内容 A 我可以从 SELECT 语句 例如 Select from MyTable 获得 SQL 注入攻击吗 B 另外 当我在 ASP NET 中使用 SQLDataSo
  • 如何将表中不存在但原始SQL中存在的实体字段设置为别名?

    假设我们有一个这样的查询 SELECT CUSTOM EXPRESSION as virtualfield FROM users 用户的实体本身具有 虚拟字段 但映射注释没有 因为表没有该字段 假设它作为原始 SQL 执行 我们如何使用上面
  • 为什么我可以像调用实例方法一样调用类方法?

    我正在查看这个例子 class SQLObject def self columns return columns if columns columns DBConnection execute2 lt lt SQL first SELEC
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 计算运行总计时出错(之前期间的累计)

    我有一张桌子 我们称之为My Table有一个Created日期时间列 在 SQL Server 中 我试图提取一个报告 该报告显示历史上有多少行My Table按月在特定时间 现在我知道我可以显示有多少added每个月 SELECT YE
  • 执行带有 EXCEPTION 的 PostgreSQL 查询会导致两条不同的错误消息

    我有一个 PostgreSQL 查询 其中包含事务和列重复时的异常 BEGIN ALTER TABLE public cars ADD COLUMN top speed text EXCEPTION WHEN duplicate colum
  • 使用间隔阈值对不同的连续时间戳记录进行分组

    我有一系列间歇性间隔的带有时间戳的 GPS 坐标 我正在使用 PostGIS 将它们渲染到地图画布上 为了渲染它们 需要使用 PostGIS 中的 ST MakeLine 聚合函数将点聚合成线 从而在地图上留下 GPS 数据丢失的间隙 数据
  • SQL - != 'NULL' 的解释

    我的SSMS代码如下 Select top 50 From FilteredContact Where statuscode 1 and emailaddress1 NULL and telephone1 NULL and address1

随机推荐