sql server 2022 不支持 json_agg 和 json_arrayagg,仅可用 json_objectagg(键值对对象)或 for json path 套子查询(模拟数组);二者均不支持 order by、where,且结果为 nvarchar(max),无法直接数值计算。

SQL Server 2022 没有 JSON_AGG,直接写会报错 Invalid object name 'JSON_AGG' —— 这不是版本低,是压根不存在。
用 JSON_OBJECTAGG 做键值对聚合(比如“部门→人数”)
它只接受两个参数:key 和 value,输出是 JSON 对象({"dept1": 12, "dept2": 8}),不是数组。
-
key必须是非 NULL 标量值;如果子查询里某行department是 NULL,整条JSON_OBJECTAGG结果就变成 NULL - 重复 key 会被覆盖:同一部门出现两次,只保留最后一次的
cnt - 不支持
ORDER BY或WHERE子句;想控制顺序,得在子查询里先ORDER BY department,但 SQL Server 不保证最终 JSON 中的字段顺序 - 不能嵌套:比如“每个部门 → 员工姓名列表”,单靠
JSON_OBJECTAGG实现不了,必须配合FOR JSON
示例:
SELECT JSON_OBJECTAGG(department, cnt) AS dept_counts FROM ( SELECT department, COUNT(*) AS cnt FROM employees GROUP BY department ) t;
用 FOR JSON PATH + 子查询做行转 JSON 数组(最接近 JSON_AGG 的效果)
这是 SQL Server 实现“多行 → JSON 数组”的唯一可靠方式,但语法约束极强。
- 子查询必须加括号,否则报语法错误
-
FOR JSON只能出现在顶层SELECT的列位置,不能放在WHERE、GROUP BY或聚合函数内部 - 空结果默认返回
NULL,不是空数组[];需用ISNULL(..., '[]')显式兜底 -
WITHOUT_ARRAY_WRAPPER用于去掉外层方括号,但仅当子查询最多返回一行时才安全,否则会拼接出非法 JSON
示例(按部门聚合员工列表):
SELECT department,
ISNULL((
SELECT name, hire_date
FROM employees e2
WHERE e2.department = e1.department
FOR JSON PATH
), '[]') AS staff
FROM employees e1
GROUP BY department;
注意 JSON_ARRAYAGG 在 SQL Server 2022 中不可用
虽然部分文档提到 JSON_ARRAYAGG,但它目前仅存在于 Azure SQL 托管实例(启用 “Always-up-to-date” 策略)、Microsoft Fabric 和 SQL Server 2025 预览版中。SQL Server 2022 本地部署实例不识别该函数,执行会报 Invalid object name 'JSON_ARRAYAGG'。
- 别被搜索结果误导:很多教程混用了 PostgreSQL / Oracle / Fabric 的语法
- 兼容性检查:运行
SELECT DATABASEPROPERTYEX(DB_NAME(), 'CompatibilityLevel'),确认 ≥ 130 是 JSON 功能基础,但不等于支持JSON_ARRAYAGG - 替代方案只能是
FOR JSON PATH套子查询,或用字符串拼接 +STRING_AGG+ 手动加引号和方括号(不推荐,易出错)
容易忽略的关键点
所有 JSON 聚合结果都是 NVARCHAR(MAX) 类型,不能直接参与数值计算或索引查找;如果要查“某个部门员工数 > 10”,必须先用 OPENJSON 解析回表,再过滤 —— 这意味着聚合后无法高效反向筛选。
另外,FOR JSON 子查询若涉及大文本或大量行,性能下降明显,建议在子查询中加 TOP 或提前过滤,避免无谓生成超长 JSON 字符串。











