FOR XML PATH 合并分组后的多行数据
分组后不能直接显示非分组字段,因为非分组字段在每个分组中可能有多个值。如果一定要把多个值显示在一行中,可以使用 FOR XML PATH 将查询结果以 XML 文档形式合并为一行一列。
子查询必须返回一行一列
-- 子查询必须返回的结果是一行一列
SELECT age, (SELECT TOP 1 name FROM [Demo].[dbo].[Person]) AS names
FROM [Demo].[dbo].[Person]
GROUP BY ageCode language: CSS (css)
-- 使用 FOR XML PATH,子查询结果也是一行一列(XML 字符串)
SELECT age, (SELECT name FROM [Demo].[dbo].[Person] FOR XML PATH) AS names
FROM [Demo].[dbo].[Person]
GROUP BY ageCode language: CSS (css)
带条件的子查询
-- 带上条件,条件中也必须使用分组字段
SELECT age, (SELECT name FROM [Demo].[dbo].[Person] WHERE age = p.age FOR XML PATH) AS names
FROM [Demo].[dbo].[Person] p
GROUP BY ageCode language: PHP (php)
去掉 XML 标记
-- path 可以传入字符串作为每个元素的根元素,传入空字符串则去掉默认的根元素
SELECT age, (SELECT name AS username FROM [Demo].[dbo].[Person] WHERE age = p.age FOR XML PATH('')) AS names
FROM [Demo].[dbo].[Person] p
GROUP BY ageCode language: PHP (php)
去掉字段名标签并拼接分隔符
-- 把字段名标签也去掉,只需要拼接一个字符串即可
SELECT age, (SELECT name + ',' FROM [Demo].[dbo].[Person] WHERE age = p.age FOR XML PATH('')) AS names
FROM [Demo].[dbo].[Person] p
GROUP BY ageCode language: PHP (php)
去掉末尾多余的分隔符
-- 使用 STUFF 函数去掉末尾多余的逗号
SELECT age, STUFF(
(SELECT ',' + name FROM [Demo].[dbo].[Person] WHERE age = p.age FOR XML PATH(''))
, 1, 1, '') AS names
FROM [Demo].[dbo].[Person] p
GROUP BY ageCode language: PHP (php)
STUFF(字符串, 起始位置, 删除长度, 替换字符串) 这里从第 1 个字符开始删除 1 个字符(即去掉开头的逗号),实现干净的多值合并效果。