H2数据库是否支持JSON_OBJECT函数?如何实现键值表反转?
问题解决:H2中JSON_OBJECT使用及键值表转宽表
一、JSON_OBJECT函数报错的解决
报错Function "JSON_OBJECT" not found通常有两个原因,对应解决方法如下:
- H2版本过低:JSON_OBJECT是H2 1.4.200及以后版本才支持的标准JSON函数,若你的H2版本低于该版本,需升级至新版H2。
- 语法使用错误:H2中JSON_OBJECT的正确语法需要明确键值对的对应关系,针对你的需求(将LABEL列值作为键,DETAIL_DATA列值作为值生成JSON对象),正确SQL写法为:
-- 标准写法 SELECT JSON_OBJECT(KEY LABEL VALUE DETAIL_DATA) FROM DB.REQUEST_DETAILS; -- 简化写法(H2 1.4.200+支持) SELECT JSON_OBJECT(LABEL, DETAIL_DATA) FROM DB.REQUEST_DETAILS;
二、键值表转宽表的实现
要将行式存储的键值对转换为列式结构,可使用条件聚合的方式实现,SQL语句如下:
SELECT MAX(CASE WHEN label = 'name' THEN details END) AS "Name", MAX(CASE WHEN label = 'email' THEN details END) AS "Email", MAX(CASE WHEN label = 'phone' THEN details END) AS "Phone" FROM DB.REQUEST_DETAILS;
说明:
- 使用
CASE WHEN匹配每个label值,提取对应的details内容; - 用
MAX(或MIN,因每个label仅出现一次)聚合函数将多行结果合并为一行; - 若后续有新增的label值,只需在SQL中新增对应的
CASE WHEN分支即可。
若需要动态适配未知数量的label(无需手动修改SQL),H2本身不支持动态行转列,此时建议在程序端先查询所有label值,再动态生成上述聚合SQL,或先通过JSON_OBJECT_AGG将所有键值对聚合成一个JSON对象,再在程序端解析为对应结构:
-- 聚合为单个JSON对象 SELECT JSON_OBJECT_AGG(label, details) AS result FROM DB.REQUEST_DETAILS;
执行后会得到类似{"name":"abc","email":"abc@email","phone":"123"}的结果,可在程序中解析为所需的列式结构。
内容的提问来源于stack exchange,提问作者Sharvari Nagesh
相关产品推荐
相关产品推荐

