如何在 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 

Demo

编辑: 如果您需要删除值而不是评论中提到的索引,只需使用变量 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 

Demo

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'