SQL Server中使用STUFF结合INNER JOIN实现多表关联查询
嘿,我明白你的需求了!在SQL Server里确实没有MySQL那种GROUP_CONCAT函数,但用STUFF配合FOR XML PATH完全能实现相同的字符串合并效果,我给你一步步讲清楚:
先确认下完整表结构(你提到的映射表我补充了常规关联结构)
Product表:存储产品基础信息
Prod_ID Name Brand 1 Name1 Brand1 2 Name2 Brand2 3 Name3 Brand3 4 Name4 Brand4 5 Name5 Brand5 6 Name6 Brand6 7 Name7 Brand7 Types表:存储产品类型信息(你写的「Type表」应该是Types吧?我按这个来啦)
Type_ID TypeName 1 TypeA 2 TypeB 3 TypeC ... ... Prod_Type映射表:关联产品与类型的中间表
Prod_ID Type_ID 1 1 1 2 2 3 ... ...
实现合并的SQL语句
直接上可用的代码,这是SQL Server里替代GROUP_CONCAT的经典写法:
SELECT p.Prod_ID, p.Name, p.Brand, -- 合并当前产品对应的所有类型名称 STUFF( (SELECT ', ' + t.TypeName FROM Prod_Type pt JOIN Types t ON pt.Type_ID = t.Type_ID WHERE pt.Prod_ID = p.Prod_ID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '' ) AS ProductTypes FROM Product p GROUP BY p.Prod_ID, p.Name, p.Brand;
关键部分解释
我拆解开给你说为什么这么写:
- 子查询 + FOR XML PATH(''):会把当前产品关联的所有类型名称用
,拼接成一个类似, TypeA, TypeB的字符串(注意开头多了个,) - .value('.', 'NVARCHAR(MAX)'):把XML格式的结果转换成普通字符串,避免出现XML转义字符(比如&变成&这种问题)
- STUFF(..., 1, 2, ''):专门用来去掉开头多余的
,——从字符串第1位开始,删除2个字符(正好是,的长度),替换为空字符串
额外小技巧
- 如果想换分隔符(比如用
;代替,),只需要修改子查询里的', '为'; ',同时STUFF的第三个参数保持2就行(因为分隔符还是两个字符) - 如果有些产品没有关联任何类型,
ProductTypes会显示NULL,要是想显示为空字符串,可以用ISNULL()包裹整个STUFF部分:ISNULL( STUFF( (SELECT ', ' + t.TypeName FROM Prod_Type pt JOIN Types t ON pt.Type_ID = t.Type_ID WHERE pt.Prod_ID = p.Prod_ID FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '' ), '' ) AS ProductTypes
内容的提问来源于stack exchange,提问作者bleyk
相关产品推荐
相关产品推荐

