SQL Server 多行转成string(用户角色Ids拼接)

问题:系统的用户T_User拥有多个角色,在T_UserRole表进行关联,角色表为T_Role。

 现在要求取出UserList;并取出每个User的角色信息,拼接成字符串类型。

预备知识:

T_UserRole 表结构: 

STUFF字符串函数是将字符串插入到另一个字符串中。它会删除开始位置第一个字符串中的指定长度的字符,然后将第二个字符串插入到开始位置的第一个字符串中,语法如下。

STUFF(<character_expression>,<开始>,<长度>,<character_expression>)
<character_expression>参数是给定的字符串数据,可以是字符或二进制数据的常量,变量或列。<start>参数是一个整数值,指定开始删除和插入的位置,可以是BIGINT类型。如果<开始>或<长度>参数为负数,则返回NULL字符串。如果<start>参数比第一个<character_expression>长,则返回一个NULL字符串。 <length>参数可以是BIGINT类型,它是一个整数,指定要删除的字符数。如果<length>比第一个<character_expression>长,则删除发生到最后一个<character_expression>中的最后一个字符。

FOR XML PATH 可以将查询结果根据行输出成XML格式。

可以参考:https://www.cnblogs.com/yasuo2/p/6433697.html

具体解析:

 1. (关键)中间橙色部分代码,是将多行转为XML格式的内容。distinct 去重。运行结果:

 2. 黑色部分代码,是截取掉前面的“,“字符,STUFF字符串函数。

// 简化一下
// tempXml = ,64,65
// 给定的字符串为@tempXml,从第1个位置开始,删除长度为1,在前面插入''(这里无字符),结果输出64,65。 select stuff({tempXml}, 1, 1, ''))
这样就是我们要的数据了

3. 蓝色部分,不为空判断。

最终代码

// 最终代码
SELECT
tu.Id, tu.Name as UserName,
ISNULL((select stuff((select distinct ',' + CONVERT(varchar, mur.RoleId)
from T_UserRole mur
                                      RIGHT JOIN T_User tus ON mur.UserId = tus.Id AND mur.IsDel = 0 AND mur.IsUsed = 1
                                      LEFT JOIN T_Role role ON role.Id = mur.RoleId
                             where tus.IsDel = 0
                               and tus.Id = tu.Id and role.IsDel = 0 and role.IsUsed = 1
                             FOR XML PATH ('')), 1, 1, '')), 0) as RoleIds,
(
select stuff((select distinct ',' + CONVERT(varchar, role.Name) from T_UserRole mur RIGHT JOIN T_User tus ON mur.UserId = tus.Id AND mur.IsDel = 0 AND mur.IsUsed = 1 LEFT JOIN T_Role role ON role.Id = mur.RoleId AND role.IsDel = 0 AND role.IsUsed = 1 where tus.IsDel = 0 and tus.Id = tu.Id and role.IsDel = 0 and role.IsUsed = 1 FOR XML PATH ('')), 1, 1, '')) as RoleNames from T_User tu where tu.IsDel = 0 ORDER BY tu.CreateTime DESC

运行结果:

猜你喜欢

转载自www.cnblogs.com/Alioo/p/11728336.html