讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在PostgreSQL中使用SQL聚合JSONB字段生成结构化对象

夏涛酱_3306

夏涛酱_3306

发布时间:2026-10-18 07:27:22

|

453人浏览过

|

来源于php中文网

原创

jsonb_object_agg()用于将键值对聚合成JSONB对象,需key显式转text,value为NULL时被忽略;jsonb_agg()+jsonb_build_object()构造对象数组;聚合空时用COALESCE(..., '{}'::jsonb)兜底。

如何在postgresql中使用sql聚合jsonb字段生成结构化对象

用 jsonb_object_agg() 把键值对聚合成 JSONB 对象

当源数据是「键-值」两列(比如 key 和 value),且你想按某一分组生成一个结构化 JSONB 对象时,jsonb_object_agg() 是最直接的选择。它会把每组内的键值对收集成一个 jsonb 对象,自动处理重复键(后出现的覆盖前一个)。

常见错误是传入非字符串类型的 key —— PostgreSQL 会报错 ERROR: field name must be type text。必须显式转换:jsonb_object_agg(key::text, value)。

使用场景举例:一张配置表 config_settings(group_id, key, value),想按 group_id 汇总为每个组一个配置对象:

SELECT group_id, jsonb_object_agg(key::text, value) AS config
FROM config_settings
GROUP BY group_id;
  • 若 value 是数字或布尔,它会被原样转为 JSONB 类型(不需要额外 to_jsonb())
  • 若 value 是 NULL,默认被忽略;如需保留 "key": null,得写成 jsonb_object_agg(key::text, coalesce(value::jsonb, 'null'::jsonb))
  • 性能上,该函数在大数据量分组时比手写 jsonb_build_object() + jsonb_concat_agg() 更快、更稳定

用 jsonb_agg() + jsonb_build_object() 构造数组内嵌对象

当你需要把多行记录“转成”一个 JSONB 对象数组(例如 API 返回的 items: [{...}, {...}]),就不能用 jsonb_object_agg() —— 它只产出单个对象,不是数组。此时组合 jsonb_agg() 和 jsonb_build_object() 是标准解法。

典型误用是漏掉 jsonb_build_object(),直接对原始行做 jsonb_agg(t.*),结果会包含系统字段(如 tableoid)、类型信息冗余,且不可控。

示例:从用户表构造带字段重命名的数组:

dmap-jsapi-skill
dmap-jsapi-skill

DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。

下载
SELECT jsonb_agg(
  jsonb_build_object(
    'id', id,
    'name', name,
    'active', is_active,
    'tags', COALESCE(tags, '[]'::jsonb)
  )
) AS users
FROM users
WHERE created_at > '2024-01-01';
  • jsonb_build_object() 参数必须成对出现(奇数个参数会报错),且键必须是文本字面量或强制转 ::text
  • 如果某字段可能为 NULL 且你希望它在 JSON 中也表现为 null,不用额外处理;但若想跳过该字段,得用 CASE WHEN ... THEN ... END 控制是否参与构建
  • 注意 jsonb_agg() 默认不保序,如需按某列排序,必须加 ORDER BY 子句:jsonb_agg(...) ORDER BY created_at DESC

聚合含嵌套结构的 JSONB 字段时避免意外扁平化

如果源字段本身是 jsonb(比如日志中的 payload),又想按某维度聚合多个 payload 到一个数组里,直接 jsonb_agg(payload) 是对的;但若试图用 jsonb_object_agg() 就会出问题 —— 它要求第一个参数是标量键,而你传的是整个 JSONB 值,PostgreSQL 会报 cannot cast type jsonb to text。

更隐蔽的问题是:有人想“合并多个 JSONB 对象的字段”,比如把每行的 metadata 合并成一个大对象。这时不能用 jsonb_object_agg(),也不能简单 jsonb_concat_agg()(它会把同名键的值拼成数组)。正确做法取决于需求:

  • 要深度合并(递归覆盖):用 jsonb_merge_agg()(需扩展 jsonb_ops 或自定义聚合函数)
  • 只要顶层键合并、冲突时后覆盖前:用 jsonb_concat_agg(metadata)(9.5+ 内置)
  • 想把所有 metadata 收进数组留待客户端处理:回到 jsonb_agg(metadata)

别忘了:所有涉及 jsonb 的聚合函数都跳过 NULL 输入项,这点和普通聚合(如 sum())一致,但容易被忽略。

空组或无匹配数据时返回空对象而非 NULL

聚合函数在没有输入行时默认返回 NULL,这常导致应用层解析失败(比如期望一个 {} 却收到 NULL)。解决方法不是加 COALESCE(..., '{}') —— 因为 COALESCE 无法改变返回类型,而 jsonb_object_agg() 返回的是 jsonb,'{}' 是 text,类型不匹配会报错。

正确写法是显式转类型:COALESCE(jsonb_object_agg(...), '{}'::jsonb)。

  • 同理,jsonb_agg() 空时返回 []::jsonb,所以应写 COALESCE(jsonb_agg(...), '[]'::jsonb)
  • 如果聚合语句带 HAVING 或复杂 WHERE,建议先用子查询或 CTE 隔离聚合逻辑,再对外层做 COALESCE,避免条件误判空组
  • 某些 ORM(如 Django 的 JSONBAggregate)默认不处理空情况,得在 SQL 层补上 COALESCE

嵌套层级越深、键名越动态,就越依赖明确的类型转换和空值兜底 —— 这些地方不写清楚,线上就容易突然返回 NULL 而不是预期结构。

热门AI工具

更多
PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4323

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

911

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1129

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6241

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3083

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6220

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

8421

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1150

2024.04.29

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

20

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 21万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 4.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn