jsonb
在Postgres 9.4或更高版本中
考虑Postgres 9.4中的jsonb
数据类型 -“ b”代表“ binary”。除此之外,还有一个相等运算符的。大多数人会想要切换。=
jsonb
关于jsonb的Depesz博客。
json
没有=
为数据类型定义运算符json
,因为没有为整个json
值建立相等性的明确定义的方法。但请参见下文。
您可以强制转换为text
,然后使用=
运算符。这很短,但是仅当您的文本表示形式匹配时才有效。本质上不可靠,除了极端情况。看到:
或者,您可以unnest
使用数组并使用->>
运算符来.. get JSON object field as text
并比较各个字段。
测试台
2行:第一个类似问题,第二个具有简单值。
CREATE TABLE tbl (
tbl_id int PRIMARY KEY
, jar json[]
);
INSERT INTO t VALUES
(1, '{"{\"value\" : \"03334/254146\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f5\"}"
,"{\"value\" : \"03334/254147\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f6\"}"
,"{\"value\" : \"03334/254148\", \"typeId\" : \"ea4e7d7e-7b87-4628-ba50-f7\"}"}')
, (2, '{"{\"value\" : \"a\", \"typeId\" : \"x\"}"
,"{\"value\" : \"b\", \"typeId\" : \"y\"}"
,"{\"value\" : \"c\", \"typeId\" : \"z\"}"}');
演示版
演示1:你可以使用array_remove()
同text
表示(不可靠)。
SELECT tbl_id
, jar, array_length(jar, 1) AS jar_len
, jar::text[] AS t, array_length(jar::text[], 1) AS t_len
, array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text) AS t_result
, array_remove(jar::text[], '{"value" : "03334/254147", "typeId" : "ea4e7d7e-7b87-4628-ba50-f6"}'::text)::json[] AS j_result
FROM tbl;
演示2:嵌套单个元素的数组和测试字段。
SELECT tbl_id, array_agg(j) AS j_new
FROM tbl, unnest(jar) AS j -- LATERAL JOIN
WHERE j->>'value' <> '03334/254146'
AND j->>'typeId' <> 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5'
GROUP BY 1;
演示3:行类型的替代测试。
SELECT tbl_id, array_agg(j) AS j_new
FROM tbl, unnest(jar) AS j -- LATERAL JOIN
WHERE (j->>'value', j->>'typeId') NOT IN (
('03334/254146', 'ea4e7d7e-7b87-4628-ba50-6a5f6e63dbf5')
,('a', 'x')
)
GROUP BY 1;
UPDATE
按照要求
最后,这就是实现您的方法UPDATE
:
UPDATE tbl t
SET jar = j.jar
FROM tbl t1
CROSS JOIN LATERAL (
SELECT ARRAY(
SELECT j
FROM unnest(t1.jar) AS j -- LATERAL JOIN
WHERE j->>'value' <> 'a'
AND j->>'typeId' <> 'x'
) AS jar
) j
WHERE t1.tbl_id = 2 -- only relevant rows
AND t1.tbl_id = t.tbl_id;
db <> 在这里拨弄
关于隐式LATERAL JOIN
:
关于取消嵌套数组:
数据库设计
为了简化您的情况,请考虑一个规范化的架构:json
值的单独表(而不是数组列),以与主表的关系为1 :。