SQL Server将子评论聚合为单行的查询实现方案咨询
SQL Server 2014 实现子评论JSON数组聚合
针对你的需求,SQL Server 2014(版本12.00.5409)没有原生的FOR JSON或ARRAY_AGG函数,但可以通过FOR XML PATH拼接字符串的方式生成JSON数组,同时解决你遇到的“Only one expression can be specified in the select list”错误。
实现思路
- 筛选出所有主评论(假设
parent_id IS NULL标识主评论,可根据实际业务调整条件)。 - 对每条主评论,关联查询下属子评论,将每个子评论转换为JSON格式的字符串。
- 用
STUFF和FOR XML PATH将子评论的JSON字符串拼接成数组格式。
完整查询语句
SELECT c.id, c.content, -- 生成子评论的JSON数组 child_comments = CASE WHEN EXISTS (SELECT 1 FROM comments WHERE parent_id = c.id) THEN '[' + STUFF(( SELECT ',' + '{"id":' + CAST(sc.id AS VARCHAR(20)) + ',"content":"' + REPLACE(sc.content, '"', '\"') + '"}' FROM comments sc WHERE sc.parent_id = c.id FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') + ']' ELSE '[]' -- 无子评论时返回空数组 END FROM comments c WHERE c.parent_id IS NULL; -- 筛选主评论,可根据实际调整条件
关键说明
- 错误解决:之前的报错是因为子查询直接返回多个字段(如
id, content),而聚合操作要求子查询返回单个表达式。这里我们将每个子评论的字段拼接成单个JSON字符串,满足子查询返回单一值的要求。 - JSON合法性:用
REPLACE(sc.content, '"', '\"')转义内容中的双引号,避免破坏JSON格式。 - 格式统一:通过
CASE WHEN EXISTS判断是否存在子评论,无子评论时返回空数组[],保证输出结构一致。
适配调整
如果你的业务中用0而非NULL标识主评论,只需将查询中的WHERE c.parent_id IS NULL改为WHERE c.parent_id = 0即可。
内容的提问来源于stack exchange,提问作者Klick
相关产品推荐
相关产品推荐

