Cin*_*dro -1 sql t-sql sql-server stored-procedures sql-server-2016
我一直无法找到解决以下困境的可行解决方案。
我正在使用 SQL Server 2016 并在数据库中有下面显示的 2 个表。
Users 桌子:
Id Name
----------
1 Lisa
2 Paul
3 John
4 Mike
5 Tom
Run Code Online (Sandbox Code Playgroud)
Role 桌子:
Id UserId Role
------------------------
1 3 Manager
2 2,4,5 Developer
3 1 Designer
Run Code Online (Sandbox Code Playgroud)
我正在寻找循环遍历Role表的T-SQL 代码,提取UserIds 并Id从Users表中检索每个的关联名称。
所以循环结果看起来像这样:
John
Paul,Mike,Tom
Lisa
Run Code Online (Sandbox Code Playgroud)
对于 SQL 服务器 2017
SELECT R1.Id,STRING_AGG(U.Name , ','),R1.Role
FROM Users U
INNER JOIN
(
SELECT R.Id,S.value AS UserId,R.Role
FROM Role R
CROSS APPLY STRING_SPLIT (UserID, ',') S
) R1
ON U.Id=R1.UserId
GROUP BY R1.ID,R1.Role
ORDER BY R1.ID;
Run Code Online (Sandbox Code Playgroud)
或者
对于 SQL SERVER 2016
WITH CTE AS
(
SELECT R2.ID,U.Name,R2.UserId,R2.Role
FROM Users U
INNER JOIN
(
SELECT R.Id,S.value AS UserId,R.Role
FROM Role R
CROSS APPLY STRING_SPLIT (UserID, ',') S
)R2
ON U.id=R2.UserId
)
SELECT DISTINCT R1.Id,
STUFF((
SELECT ',' + name
FROM CTE R3
WHERE R1.Role = R3.Role
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS NAME
,R1.Role
FROM CTE AS R1;
Run Code Online (Sandbox Code Playgroud)
或者
对于旧版本
With CTE AS
(
SELECT r.id,
u.name,
r.Role
FROM Users u
INNER JOIN Role r
ON ',' + CAST(r.Userid AS NVARCHAR(20)) + ',' like '%,' + CAST(u.id AS NVARCHAR(20)) + ',%'
)
SELECT DISTINCT id,
STUFF((
SELECT ',' + name
FROM CTE md
WHERE T.Role = md.Role
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS NAME,
Role
FROM
CTE AS T
ORDER BY id
Run Code Online (Sandbox Code Playgroud)
输出
id NAME Role
1 John Manager
2 Paul,Mike,Tom Developer
3 Lisa Designer
Run Code Online (Sandbox Code Playgroud)
演示