postgresql 从Postgres中的JSON列表中删除JSON键/值对

lnvxswe2  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(177)

我有JSON格式的数据(注意:而不是jsonb)列,可以类似于以下任何一种:

[{"question": "Did you upload the file?"}]
or
[{"question": "Did you upload the file?"}, 'choice_1', 'Yes']
or
null
or
[]
or
etc...

我正在尝试从值列表中删除所有出现question键及其值的地方。
我尝试了无数的方法都没有用,包括更新表set column = column - 'question',使用jsonb函数的组合,似乎都没有工作。我怀疑这是因为这个列表不是像['a', 'b', 'c']这样简单的值,我只是还没有找到正确的方法组合。
如果列包含{'question': 'some random question'}键,我希望从列表中删除整个键/值对。
示例(注:实际上仅更改了以下第一项):

[{'color': 'blue'}, {'question': 'what time is it'}] **->** [{'color': 'blue'}]

[{'something': 'something_else'}] **->** [{'something': 'something_else'}}

[] **->** []
7bsow1i6

7bsow1i61#

老实说,如果您遇到这种麻烦的情况,您可能需要重新考虑您的数据模式。但是,我认为这是你想要的:

WITH array_elements (e) AS (
    SELECT jsonb_array_elements(
        '["z", 1, {"question":"something", "foo":"bar"}, 3, {"other":"object"}]'::jsonb
    )
)
, filtered_elements AS (
    SELECT e FROM array_elements WHERE NOT e ? 'question'
)
SELECT jsonb_agg(e) FROM filtered_elements;

┌──────────────────────────────────┐
│            jsonb_agg             │
├──────────────────────────────────┤
│ ["z", 1, 3, {"other": "object"}] │
└──────────────────────────────────┘
(1 row)

我将其作为一系列CTE(WITH子句)来执行,以使其更易理解。
我们在JSON数组中随机选择内容,并将其转换为每个元素的一行。
然后我们过滤掉任何以“question”作为顶级键的对象。
然后我们把它们放回数组中。
注1:我不认为我们可以 * 保证100%* 数组的顺序将被保留。几乎可以肯定的是,因为序列中没有任何东西可以打乱它们从初始JSON数组中出来的顺序。
注意2:可能有一些方法可以用JSON路径查询来做到这一点,但我对它不够熟悉,无法尝试。

相关问题