在一行中返回SQL中的多对一组合
我有下列表格在一行中返回SQL中的多对一组合,sql,sql-server,performance,subquery,one-to-many,Sql,Sql Server,Performance,Subquery,One To Many,我有下列表格 User --------------------------- UserID, FirstName, LastName Role --------------------------- RoleID, UserID, RoleName 假设角色和用户之间存在多对一的关系,我可以在一个查询中返回一个用户以及他们可能在一行中的所有角色的最佳方式是什么 以前我总是在单独的查询中加载角色(或类似的数据),但问题是,如果您的数据增长过快,这种技术就会变得太慢。将您的数据放入包含更多列
User
---------------------------
UserID, FirstName, LastName
Role
---------------------------
RoleID, UserID, RoleName
假设角色和用户之间存在多对一的关系,我可以在一个查询中返回一个用户以及他们可能在一行中的所有角色的最佳方式是什么
以前我总是在单独的查询中加载角色(或类似的数据),但问题是,如果您的数据增长过快,这种技术就会变得太慢。将您的数据放入包含更多列的单行并不比返回包含更少列的多行更有效。创建和销毁连接可能是您所做的最昂贵的操作,因此您可能会考虑创建一个存储过程来包装两个查询,然后使用访问结果。
WITH cte (userId, roleList, roleNameTemp, level)
as
(
SELECT userId
, CAST( '' AS VARCHAR(max) )
, CAST( '' AS VARCHAR(200) )
, 0 level
FROM Role
GROUP BY UserId
UNION ALL
SELECT r.userId
, roleList +
CASE WHEN level = 0 THEN '' ELSE ', ' END + RoleName
, CAST( RoleName AS VARCHAR(200))
, level + 1
FROM CTE c
INNER JOIN Role r ON c.userId = r.userid
WHERE r.RoleName > c.roleNameTemp
)
SELECT UserId
,FirstName
,LastName
,roleList
FROM
(
SELECT u.UserId
,u.FirstName
,u.LastName
,c.roleList
,ROW_NUMBER() OVER (Partition by c.userid order by level desc) rowNumber
FROM cte c
INNER JOIN [User] u on c.userId = u.UserId
) r
WHERE rownumber = 1
请参见使用光标或CTE获取单行数据