PostgreSQL使用另一列的值更新JSONB列

时间:2016-03-27 10:01:34

标签: sql postgresql postgresql-9.4 jsonb

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

nameb

这样{"en": "$name"}将成为$name,其中name name | nameb --------------------------------------+------------ hello | {} world | {} 字段中的值。

例如:

SELECT name,nameb

之前:

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

后:

UPDATE SET whatever = (SELECT ...)

使用regualar类型我可以UPDATE merchants SET nameb = (SELECT '{"en": "fillme!"}'::jsonb);,但如何使用jsonb执行此操作?

<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Name: " android:id="@+id/textView27" android:layout_row="0" android:layout_column="0" style="@style/Base.TextAppearance.AppCompat.Title" android:textSize="22dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Idea Gallery" android:id="@+id/textView28" android:layout_row="0" android:layout_column="1" android:textSize="22dp" /> <TextView style="@style/Base.TextAppearance.AppCompat.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Address: " android:id="@+id/textView29" android:layout_row="1" android:layout_column="0" android:textSize="22dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Shop No 5, Akshay Apartment, Kalwa, Thane - 400605, Opposite Pramila Hospital " android:id="@+id/textView30" android:layout_row="1" android:layout_column="1" android:textSize="22dp" /> <TextView style="@style/Base.TextAppearance.AppCompat.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Contact:" android:id="@+id/textView31" android:layout_row="2" android:layout_column="0" android:textSize="22dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="022 - 385[enter image description here][1]39146" android:id="@+id/textView32" android:layout_row="2" android:layout_column="1" android:textSize="22dp" /> </GridLayout> 有效,但如何设置&#34; fillme!&#34;来自另一个领域的价值?

3 个答案:

答案 0 :(得分:2)

我找到了解决方案:

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;

不确定它是否正确,但它有效

答案 1 :(得分:2)

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

所以做你想做的事:

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

使用 json_build_object 我们正在根据“name”列中的值动态地制作 {"en": "hello"}, {"en": "world"} .. 之后,我们可以简单地使用 || 连接到 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 更方便。

答案 2 :(得分:0)

是的,jsonb_build_object 是最佳选择。

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

创建

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