讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

Seko
Seko

AI短剧一键生成成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

Laper
Laper

剧本策划到成片协作

如何在PostgreSQL中利用标量子查询构建复杂JSON结构

酷杰小哥_6541

酷杰小哥_6541

发布时间:2026-11-13 11:09:38

|

178人浏览过

|

来源于php中文网

原创

PostgreSQL中JSON_BUILD_OBJECT要求标量子查询必须返回单行,否则报错;正确做法是用JSON_AGG聚合多行、COALESCE处理空值、LATERAL连接替代嵌套子查询,并注意手动转义特殊字符。

如何在postgresql中利用标量子查询构建复杂json结构

标量子查询必须返回单行,否则 JSON_BUILD_OBJECT 直接报错

PostgreSQL 的 JSON_BUILD_OBJECT 不接受多行结果作为某个键的值。如果你写成 SELECT JSON_BUILD_OBJECT('id', id, 'tags', (SELECT tag FROM tags WHERE post_id = posts.id)),只要某篇 posts 对应多个 tags,就会触发错误:more than one row returned by a subquery used as an expression。

这不是 JSON 函数的问题,而是标量子查询本身的语义限制:它只能返回 0 或 1 行。常见误操作是忘了聚合、漏了 LIMIT 1、或没加 GROUP BY。

  • 安全做法是用 (SELECT JSON_AGG(JSON_BUILD_OBJECT('name', tag)) FROM tags WHERE post_id = posts.id)
  • 若允许空数组,加 COALESCE(..., '[]'::json);若允许 NULL,不加也行,但前端需兼容
  • 想取第一个标签?用 (SELECT tag FROM tags WHERE post_id = posts.id LIMIT 1),但注意这不保证顺序,建议加 ORDER BY created_at

LEFT JOIN LATERAL 是替代标量子查询的更可控方案

当嵌套层级变深(比如文章 → 分类 → 分类下的属性),硬塞多个标量子查询会难读、难调、性能差。这时 LATERAL 能把子查询“拉平”为可连接的行集,再配合 JSON_AGG 组装。

例如查文章及其所有分类及每个分类的元数据:

JSON Toolkit
JSON Toolkit

JSON文件多功能工具。支持格式化、验证、压缩、键排序及点记法路径查询。零依赖。

下载
SELECT JSON_BUILD_OBJECT(
  'id', p.id,
  'title', p.title,
  'categories', COALESCE(c.cat_list, '[]'::json)
)
FROM posts p
LEFT JOIN LATERAL (
  SELECT JSON_AGG(
    JSON_BUILD_OBJECT(
      'name', c.name,
      'meta', COALESCE(m.meta_list, '[]'::json)
    )
  ) AS cat_list
  FROM categories c
  LEFT JOIN LATERAL (
    SELECT JSON_AGG(JSON_BUILD_OBJECT('key', k.key, 'value', k.value)) AS meta_list
    FROM category_meta k
    WHERE k.category_id = c.id
  ) m ON true
  WHERE c.post_id = p.id
) c ON true;
  • LATERAL 允许子查询引用外层表字段(如 c.id),这是普通 JOIN 做不到的
  • 每层 LATERAL 都要确保只返回一行(靠 JSON_AGG 聚合),否则外层 JSON_BUILD_OBJECT 仍会报错
  • 用 LEFT JOIN LATERAL 而非 INNER JOIN LATERAL,避免丢失无分类的文章

字符串字段含双引号或反斜杠时,JSON_BUILD_OBJECT 不自动转义

JSON_BUILD_OBJECT 只做类型转换,不做内容清洗。如果字段值本身含 " 或 (比如用户输入的 He said: "Hi!"),直接拼进 JSON 会导致语法错误或解析失败。

  • 简单处理:用 REPLACE(field, '"', '\"') 和 REPLACE(..., '', '\') 手动转义(注意顺序:先处理反斜杠)
  • 更稳妥:在应用层序列化前统一处理,数据库层尽量不承担转义责任
  • 验证方式:把结果用 json_typeof() 检查是否为 object,或用 json_valid()(PostgreSQL 16+)判断合法性

空值和缺失键会让嵌套结构断裂,得靠 COALESCE + 显式默认值兜底

标量子查询返回 NULL 时,JSON_BUILD_OBJECT 会把对应键设为 null 值,而不是跳过该字段。而很多前端或 API 规范要求“不存在的字段不出现”,或者要求空数组而非 null。

  • 数组字段:始终用 COALESCE((SELECT ...), '[]'::json),不能依赖 JSON_AGG 自动补空 —— 它在子查询无结果时返回 NULL,不是空数组
  • 对象字段:用 COALESCE((SELECT JSON_BUILD_OBJECT(...)), '{}'::json)
  • 标量字段(如 author_name):用 COALESCE(author_name, '') 或 NULLIF(author_name, '') 控制是否保留键

最易被忽略的是多层嵌套中某一层子查询意外返回空,导致外层整个 JSON 构建中断或结构错位 —— 必须每一层都独立做空值防护,不能只在外层包一次 COALESCE。

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

WorkBuddy

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

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

豆包大模型

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

DeepSeek

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

讯飞智作

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

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2335

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3822

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1276

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4439

2025.09.10

postgresql常用命令
postgresql常用命令

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、l、c、dt、d table_name、du、i file_name、e和q等。本专题为大家提供postgresql相关的文章、下载、课程内容,供大家免费下载体验。

233

2023.10.10

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

4949

2023.11.02

postgresql常用命令有哪些
postgresql常用命令有哪些

postgresql常用命令psql、createdb、dropdb、createuser、dropuser、l、c、dt、d table_name、du、i file_name、e和q等。更详细的postgresql常用命令,大家可以访问下面的文章。

647

2023.11.16

postgresql常用命令介绍
postgresql常用命令介绍

postgresql常用命令有l、d、d5、di、ds、dv、df、dn、db、dg、dp、c、pset、show search_path、ALTER TABLE、INSERT INTO、UPDATE、DELETE FROM、SELECT等。想了解更多postgresql的相关内容,可以阅读本专题下面的文章。

1396

2023.11.20

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

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

精品课程

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

共101课时 | 21.3万人学习

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

共39课时 | 4.9万人学习

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

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