【问题标题】:Querying a json type string Postgres查询 json 类型字符串 Postgres
【发布时间】:2026-02-01 06:50:01
【问题描述】:

我的数据库中有一个带有 json 结构的文本列。 Postgres v.10

它可能看起来像这样:

{"pe_cd":"07","me_cd":"006","mf":"4.0","mfm":"4.0","pot":null,"earliestDate":[{"date":"2019-07-01","_destroy":false},{"date":"2020-01-01","_destroy":""}],"earliestDate2":null,"leavingDate":null}

如果 earlyDate2 = null 那么我需要进行更新查询并用最早日期 [] 的第一个日期填充它。在这种情况下 2019-07-01

在这种情况下的目标应该是:

{"pe_cd":"07","me_cd":"006","mf":"4.0","mfm":"4.0","pot":null,"earliestDate":[{"date":"2019-07-01","_destroy":false},{"date":"2020-01-01","_destroy":""}],"earliestDate2":"2019-07-01","leavingDate":null} 

我该如何编写这个更新查询?

Fiddle

【问题讨论】:

    标签: arrays json string postgresql


    【解决方案1】:

    要查询您的 json 类型字符串,您可以这样做:

    `SELECT * FROM yourtable
    WHERE json_like_column::JSON->'earliestDate' 为空

    `

    :: 会将您的字符串转换为 JSON 并且 -> 将从您的 json 中获取 'eraliestDate' 字段。您还可以使用 ->> 将该字段的值转换为字符串。

    【讨论】:

    • 您应该将WHERE json_like_column::JSON->'earliestDate' IS NULL 替换为WHERE json_like_column::JSON->'earliestDate' = 'null' :: json,因为json 'null' 值与postgres 的NULL 值不同。
    【解决方案2】:

    这是我为你想出的:

    WITH null_dates AS
    ( -- Find the records with a NULL earliestDate2 and expand the dates stored
        SELECT id, (jsonb_array_elements((attr::JSONB)->'earliestDate')->>'date')::DATE as d
          FROM test
         WHERE (attr::JSONB)->>'earliestDate2' IS NULL
    )
    UPDATE test t
       SET attr = ((attr::JSONB)||jsonb_build_object('earliestDate2', sub.edate))::TEXT
      FROM
         ( -- Get the min date per ID from CTE (null_dates)
             SELECT id
                  , MIN(d) AS edate
               FROM null_dates
              GROUP BY id
         ) sub
     WHERE t.id = sub.id
    ;
    

    Here 是一个展示它的小提琴。

    【讨论】:

    • jsonb_array_elements 在 v.10 中不存在 :(
    • 它在 Postgres 10 的文档中列出,当我在 Postgres 10 中运行该小提琴时,它就完成了。很确定我也在 v10 的实践中使用过它。你有错误吗?
    • 你的小提琴使用的是 v9.3
    • 我一定犯了一些错误,它似乎可以工作,但我仍然无法进行更新。我认为问题在于此列 attr 是我的数据库中的一个文本字段。我需要将所有内容都转换为文本吗?错误:“::”处或附近的语法错误。
    • 我将在此处更新示例以使用TEXT,但将其存储为JSONJSONB 会是更好的解决方案。很确定你可以在INSERT 语句中传递TEXT,Postgres 会隐式转换它。