能否通过数据库查询实现JSONB中Food类Pizza的增改操作?
可以通过查询语句实现这个需求(以PostgreSQL为例)
当然可以实现!如果你的数据库支持JSON/JSONB类型的操作(比如常用的PostgreSQL),完全能用查询语句搞定这个「存在则更新,不存在则插入」的需求。我拿你给的JSON结构举个实际例子,用PostgreSQL的JSONB操作来演示:
假设你的表结构是这样的(比如表名为product_data,存储JSON的字段为data):
CREATE TABLE product_data ( id SERIAL PRIMARY KEY, data JSONB NOT NULL );
先把你提供的初始数据插入表中:
INSERT INTO product_data (data) VALUES ('{ "type_A": { "Food": [ { "Pizza": 1 }, { "Pasta": 4 }, { "Rosted nuts": 2 } ], "drinks": [ { "coka cola": 8 }, { "moka": 1 }, { "wine": 16 } ] } }');
实现需求的核心查询语句
我们可以用CASE分支结合PostgreSQL的JSONB函数来完成这个逻辑,下面的语句会根据Pizza是否存在,自动执行更新或添加操作:
UPDATE product_data SET data = CASE -- 先检查Food数组里有没有带Pizza的条目 WHEN data->'type_A'->'Food' @> '[{"Pizza": 0}]'::JSONB THEN -- 存在的话:找到Pizza的位置,把它的数量改成请求给定的值(示例中改成5) jsonb_set( data, array['type_A', 'Food', ( SELECT idx - 1 FROM jsonb_array_elements(data->'type_A'->'Food') WITH ORDINALITY arr(elem, idx) WHERE elem ? 'Pizza' )::TEXT, 'Pizza'], '"5"'::JSONB ) ELSE -- 不存在的话:把新的Pizza条目加到Food数组的末尾 jsonb_set( data, array['type_A', 'Food'], (data->'type_A'->'Food') || '[{"Pizza": 5}]'::JSONB ) END WHERE id = 1; -- 这里替换成你实际的行筛选条件,比如根据请求的标识字段
关键逻辑解释
data->'type_A'->'Food' @> '[{"Pizza": 0}]'::JSONB:用@>操作符检查Food数组中是否包含带有Pizza键的对象(值随便填,只要键存在就会匹配)。jsonb_array_elements(...) WITH ORDINALITY:遍历Food数组,找到Pizza条目的索引位置(因为PostgreSQL数组索引从0开始,所以要把返回的序号减1)。jsonb_set:用来修改JSONB字段指定路径的值;||操作符用来拼接JSON数组,实现添加新元素的效果。
如果是其他数据库(比如MySQL),也有对应的JSON函数可以实现类似逻辑,核心思路都是先判断目标条目是否存在,再分支执行更新或插入操作。
内容的提问来源于stack exchange,提问作者tester test
相关产品推荐
相关产品推荐

