【问题标题】:PostgreSQL update JSONB column with value from another columnPostgreSQL 用另一列的值更新 JSONB 列
【发布时间】:2016-07-14 18:03:31
【问题描述】:

我想将数据从一列(varchar)迁移到另一列(jsonb)

   Column   |            Type             |                       Modifiers                        
------------+-----------------------------+--------------------------------------------------------
 id         | integer                     | not null default nextval('merchants_id_seq'::regclass)
 name       | character varying           | not null
 nameb      | jsonb                       | not null default '{}'::jsonb

这样nameb 将变为{"en": "$name"},其中$name 是name 字段中的值。

例如:

选择名称,名称b

之前:

                 name                 |   nameb    
--------------------------------------+------------
 hello                                | {} 
 world                                | {}

之后:

                 name                 |   nameb    
--------------------------------------+------------
 hello                                | {"en": "hello"}
 world                                | {"en": "world"}

使用常规类型我可以做到UPDATE SET whatever = (SELECT ...),但是如何使用 jsonb 做到这一点?

UPDATE merchants SET nameb = (SELECT '{"en": "fillme!"}'::jsonb); 有效,但如何设置“fillme!”另一个字段的值?

【问题讨论】:

    标签: sql postgresql postgresql-9.4 jsonb


    【解决方案1】:

    我找到了解决办法:

    UPDATE merchants AS m1 
    SET nameb = (
      SELECT row_to_json(t) FROM (
        SELECT name as en FROM merchants AS m2 WHERE m1.id = m2.id
      ) t
    )::jsonb;
    

    不确定是否正确,但有效

    【讨论】:

      【解决方案2】:

      这可以通过 jsonb_build_object 函数来完成,它允许您从简单的数据类型构建 json 对象。

      所以做你想做的事:

      update merchants set nameb = nameb || jsonb_build_object('en', name)
      

      使用 json_build_object 我们正在制作 {"en": "hello"}, {"en": "world"} ..动态地基于 "name" 列的值。 之后,我们可以简单地使用 || 连接到 jsonb 值。运算符。

      如果 nameb 为 NULL,这将不起作用,因为 NULL 将“吃掉”一切,结果将再次为 NULL。 在这种情况下,我建议使用 COALESCE:

      update merchants set nameb = COALESCE(nameb, '{}') || jsonb_build_object('en', name)
      

      实现相同的另一种方法是使用 jsonb_set 函数。对于这种特殊情况,这有点过头了,但是如果您需要在 json 的某个深处设置一些键,它可能会很方便:

      update merchants set nameb = jsonb_set(nameb, '{en}', ('"' || name || '"')::jsonb)
      

      这看起来很奇怪,因为我们必须构造由引号包围的字符串,即:'"hello"' 将其设置为 'en' 键的值。如果你需要设置一些 json,jsonb_build_object 更方便。

      【讨论】:

        【解决方案3】:

        是的,jsonb_build_object 是最佳选择。

        UPDATE merchants 
        SET nameb = jsonb_build_object('en', "name", 
                                       'cs', '')
        WHERE ...
        

        创建

                     name         |   nameb    
        --------------------------+------------------------------
         hello                    | {"en": "hello", "cs": ""}
         world                    | {"en": "world", , "cs": ""}
        

        【讨论】:

          猜你喜欢
          • 2021-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-03
          • 2015-07-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多