SQL Server 2019如何实现带展开运算符效果的JSON构建
SQL Server 生成JSON时实现嵌套对象字段展开的方案
要实现类似JS展开运算符...users[n]把用户全量属性嵌入user节点的效果,直接用SQL Server原生FOR JSON PATH的列前缀嵌套规则即可,不需要额外做二次JSON处理。
- 核心原理:
FOR JSON PATH会自动将列名中带.前缀的字段归到同一个嵌套对象下,你只要把关联到的用户表所有字段都加上user.前缀,再把需要追加的last_message、topic字段也加上相同前缀,最终生成的JSON就会自动把这些字段合并到同一个user对象里,和展开运算符先铺全量字段、再追加覆盖字段的逻辑完全一致。 - 基础静态写法(字段固定场景):
SELECT m.id, -- 替换成你users表的所有实际字段,全部加[user.字段名]别名 u.id AS [user.id], u.username AS [user.username], u.email AS [user.email], u.avatar AS [user.avatar], u.register_time AS [user.register_time], -- 额外追加的两个字段同样放到user节点下 m.last_message AS [user.last_message], m.topic AS [user.topic], m.unread FROM messages m -- 关联对应用户表数据 INNER JOIN users u ON m.user_id = u.id FOR JSON PATH;
- 动态写法(适配users表字段变动场景):
如果不想每次users表增删字段都手动改SQL,可以用系统视图自动拼接用户字段,避免手动维护列清单:
DECLARE @user_columns NVARCHAR(MAX); -- 自动读取users表所有非计算列,生成带user前缀的别名片段 SELECT @user_columns = STRING_AGG( 'u.' + QUOTENAME(name) + ' AS [user.' + REPLACE(name, ']', ']]') + ']', ', ' ) FROM sys.columns WHERE object_id = OBJECT_ID('users') AND is_computed = 0; DECLARE @exec_sql NVARCHAR(MAX) = N' SELECT m.id, ' + @user_columns + ', m.last_message AS [user.last_message], m.topic AS [user.topic], m.unread FROM messages m INNER JOIN users u ON m.user_id = u.id FOR JSON PATH; '; -- 执行生成最终JSON EXEC sp_executesql @exec_sql;
生成的结果中,user节点会自动包含对应用户的所有属性,末尾追加你需要的last_message、topic字段,和你预期的结构完全匹配。
不推荐大数据量场景下用
JSON_MODIFY做二次合并,性能比直接关联查询低30%以上,字段多的时候差距更明显。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

