如何在 PostgreSQL 中删除 jsonb 整数数组中的元素
How to remove an element in jsonb integer array in PostgreSQL
在 Postgres 上,在名为“photo”的 table 中,我有一个名为“id_us”的 jsonb 列,其中包含一个 json 整数数组,就像这样一个 [1,2,3,4]
例如,我想找到删除元素 3 的查询。
我能得到的更近的是这个
SELECT jsonb_set(id_us, ''
, (SELECT jsonb_agg(val)
FROM jsonb_array_elements(p.id_us) x(val)
WHERE val <> jsonb '3')
) AS id_us
FROM photo p;
知道如何解决这个问题吗?
谢谢!
可以使用包含JSONB_AGG()
函数的子查询,同时过滤掉索引值3
(从1开始索引)如
WITH p AS
(
SELECT JSONB_AGG(j) AS js
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE idx != 3
)
UPDATE photo
SET id_us = js
FROM p
编辑: 如果您需要删除值而不是评论中提到的索引,只需使用变量 j
转换为数字
WITH p AS
(
SELECT JSONB_AGG(j) AS js
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE j::INT != 18
)
UPDATE photo
SET id_us = js
FROM p
P.S:使用JSONB_SET()
,删除元素的逗号分隔位置以及引号仍将保留在以下
中
WITH p AS
(
SELECT ('{'||idx-1||'}')::TEXT[] AS idx
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE j::INT = 18
)
UPDATE photo
SET id_us = JSONB_SET(id_us,idx,'""')
FROM p;
SELECT * FROM photo;
id_us
-----------------
[127, 52, "", 44]
我 运行 遇到过类似的问题,它源于 -
运算符。此运算符被重载以接受文本或整数,但对每种类型的行为不同。使用文本将按值删除,使用整数将按索引删除。但是如果你的值是一个整数呢?那你真倒霉...
如果可能,您可以尝试将 jsonb 整数数组更改为 jsonb 字符串数组(整数),然后 -
运算符应该可以顺利运行。
例如
'{1,2,3}' - 2 = '{1,2}' -- removes index 2
'{1,2,3}' - '2' = '{1,2,3}' -- removes values == '2' (but '2' != 2)
'{"1","2","3"}' - 2 = '{"1","2"}' -- removes index 2
'{"1","2","3"}' - '2' = '{"1","3"}' -- removes values == '2'
在 Postgres 上,在名为“photo”的 table 中,我有一个名为“id_us”的 jsonb 列,其中包含一个 json 整数数组,就像这样一个 [1,2,3,4] 例如,我想找到删除元素 3 的查询。 我能得到的更近的是这个
SELECT jsonb_set(id_us, ''
, (SELECT jsonb_agg(val)
FROM jsonb_array_elements(p.id_us) x(val)
WHERE val <> jsonb '3')
) AS id_us
FROM photo p;
知道如何解决这个问题吗? 谢谢!
可以使用包含JSONB_AGG()
函数的子查询,同时过滤掉索引值3
(从1开始索引)如
WITH p AS
(
SELECT JSONB_AGG(j) AS js
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE idx != 3
)
UPDATE photo
SET id_us = js
FROM p
编辑: 如果您需要删除值而不是评论中提到的索引,只需使用变量 j
转换为数字
WITH p AS
(
SELECT JSONB_AGG(j) AS js
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE j::INT != 18
)
UPDATE photo
SET id_us = js
FROM p
P.S:使用JSONB_SET()
,删除元素的逗号分隔位置以及引号仍将保留在以下
WITH p AS
(
SELECT ('{'||idx-1||'}')::TEXT[] AS idx
FROM photo
CROSS JOIN JSONB_ARRAY_ELEMENTS(id_us)
WITH ORDINALITY arr(j,idx)
WHERE j::INT = 18
)
UPDATE photo
SET id_us = JSONB_SET(id_us,idx,'""')
FROM p;
SELECT * FROM photo;
id_us
-----------------
[127, 52, "", 44]
我 运行 遇到过类似的问题,它源于 -
运算符。此运算符被重载以接受文本或整数,但对每种类型的行为不同。使用文本将按值删除,使用整数将按索引删除。但是如果你的值是一个整数呢?那你真倒霉...
如果可能,您可以尝试将 jsonb 整数数组更改为 jsonb 字符串数组(整数),然后 -
运算符应该可以顺利运行。
例如
'{1,2,3}' - 2 = '{1,2}' -- removes index 2
'{1,2,3}' - '2' = '{1,2,3}' -- removes values == '2' (but '2' != 2)
'{"1","2","3"}' - 2 = '{"1","2"}' -- removes index 2
'{"1","2","3"}' - '2' = '{"1","3"}' -- removes values == '2'