我有2个表:用户和角色。
用户表格列:
UserId FirstName Lastname
角色表格列:
RoleId UserId ParentId
我希望能够从表示名为 ParentName 的列的这两个表中获取日期。
让我们说我有这些数据:
用户表:
UserId FirstName Lastname
1 John Doe
2 Jane Smith
3 John Smith
角色表:
RoleId UserId ParentId
1 1 NULL
2 2 1
3 3 2
所以我想要这张表:
UserId FirstName Lastname RoleId ParentId ParentName
1 John Doe 1 NULL NULL
2 Jane Smith 2 1 John Doe
3 John Smith 3 2 Jane Smith
我试过,但我不能。我试过INNER JOIN,OUTER JOIN,Subqueries但我无法得到我想要的东西。
在连接两张桌子时,我有这个:
SELECT UserId, FirstName, Lastname, RoleId, ParentId
FROM Users INNER JOIN Roles ON Users.UserId = Roles.UserId
在加入自递归角色表时,我有这个:
SELECT ChildUsers.UserId, ChildUsers.RoleId, ParentUsers.UserId, ParentUsers.RoleId, Users.LastName
FROM Roles AS ChildUsers
LEFT JOIN Roles AS ParentUsers ON ChildUsers.ParentId = ParentUsers.RoleId
INNER JOIN Users ON Users.UserId = ParentUsers.UserId
但我无法得到我想要的东西。我怎么能得到它?
----------- --------------- UPDATE
这是我自己的解决方案:
SELECT Roles.RoleID, LastName, Parent.ParentName FROM
Roles INNER JOIN Users ON Users.UserID = Roles.UserID LEFT JOIN
(SELECT LastName AS ParentName, RoleID FROM Users INNER JOIN Roles ON Users.UserID = Roles.UserID) Parent ON Parent.RoleID = Roles.ParentID
但我选择LukStorms解决方案作为答案。
答案 0 :(得分:1)
获得预期的结果?
如果ParentId包含RoleId,那么这应该有效:
SELECT
r.UserId,
u.FirstName,
u.Lastname,
r.RoleId,
r.ParentId,
pu.FirstName+' '+pu.LastName AS ParentName
FROM Roles r
LEFT JOIN Users u ON r.UserId = u.UserId
LEFT JOIN Roles pr on r.ParentId = pr.RoleId
LEFT JOIN Users pu on pr.UserId = pu.UserId
但是如果ParentId是Users表的外键:
SELECT
r.UserId,
u.FirstName,
u.Lastname,
r.RoleId,
r.ParentId,
p.FirstName+' '+p.LastName AS ParentName
FROM Roles r
LEFT JOIN Users u ON r.UserId = u.UserId
LEFT JOIN Users p on r.ParentId = p.UserId
答案 1 :(得分:0)
尝试此查询: -
Create table Users (UserId INT, FirstName VARCHAR(255), LastName
VARCHAR(255));
INSERT INTO Users VALUES(1,'John','Doe');
INSERT INTO Users VALUES(2,'Jane','Smith');
INSERT INTO Users VALUES(3,'John','Smith');
Create table Roles(RoleId INT, UserId INT, ParentId INT);
INSERT INTO ROles VALUES(1,1,NULL);
INSERT INTO ROles VALUES(2,2,1);
INSERT INTO ROles VALUES(3,3,2);
SELECT a.*,concat(b.FirstName,' ',b.Lastname) as ParentName
from
(
SELECT a.UserId, FirstName, Lastname, RoleId, ParentId
FROM Users a INNER JOIN Roles b ON a.UserId = b.UserId
) a
left join
Users b
on a.ParentId=b.userid;
输出: -
UserId FirstName Lastname RoleId ParentId ParentName
1 1 John Doe 1 NULL
2 2 Jane Smith 2 1 John Doe
3 3 John Smith 3 2 Jane Smith
答案 2 :(得分:0)
使用此查询可以获得所需的结果。由于您只需要2级深度,因此无需递归查询即可完成
DECLARE @Users TABLE (UserId INT, FirstName VARCHAR(255), LastName VARCHAR(255))
INSERT INTO @Users VALUES
(1,'John','Doe'),
(2,'Jane','Smith'),
(3,'John','Smith')
DECLARE @ROles TABLE (RoleId INT, UserId INT, ParentId INT)
INSERT INTO @ROles VALUES
(1,1,NULL),
(2,2,1),
(3,3,2)
SELECT u.UserId, u.FirstName, u.LastName, r.RoleId, r.ParentId, p.ParentName
FROM @Users AS u
LEFT OUTER JOIN @Roles AS r ON r.UserId = u.UserId
LEFT OUTER JOIN
(SELECT r.UserId AS ParentId, up.FirstName + ' ' + up.LastName AS ParentName
FROM @ROles AS r
INNER JOIN
@Users AS up ON up.UserId = r.ParentId) AS p ON p.ParentId = u.UserId
更新:添加结果
UserId FirstName LastName RoleId ParentId ParentName
1 John Doe 1 NULL NULL
2 Jane Smith 2 1 John Doe
3 John Smith 3 2 Jane Smith
答案 3 :(得分:0)
代码解释:
CTE 以获取用户详细信息和角色。
使用 CTELEFT JOIN 获取父信息。用户的ParentId与Parent(也是用户)UserId一起加入ParentName。
(注意:您可以在没有第二个连接的情况下运行cte separtely来查看输出。然后运行整个以查看它是如何加入的。)
CREATE TABLE [dbo].[Roles](
[RoleId] [int] NULL,
[UserId] [int] NULL,
[ParentId] [int] NULL
)
;
CREATE TABLE [dbo].[Users](
[UserId] [int] NULL,
[FirstName] [varchar](20) NULL,
[Lastname] [varchar](20) NULL
);
INSERT [dbo].[Roles] ([RoleId], [UserId], [ParentId]) VALUES (1, 1, NULL);
INSERT [dbo].[Roles] ([RoleId], [UserId], [ParentId]) VALUES (2, 2, 1);
INSERT [dbo].[Roles] ([RoleId], [UserId], [ParentId]) VALUES (3, 3, 2);
INSERT [dbo].[Users] ([UserId], [FirstName], [Lastname]) VALUES (1, N'John', N'Doe');
INSERT [dbo].[Users] ([UserId], [FirstName], [Lastname]) VALUES (2, N'Jane', N'Smith');
INSERT [dbo].[Users] ([UserId], [FirstName], [Lastname]) VALUES (3, N'John', N'Smith');
with cteUsers AS
(
select u.UserId, u.FirstName, u.Lastname, r.RoleId, r.ParentId
from Users AS u
inner join Roles AS r
on u.UserId=r.UserId
)
select
cteUsers.UserId
,cteUsers.FirstName
,cteUsers.Lastname
,cteUsers.RoleId
,cteUsers.ParentId
,(p.FirstName + ' ' + p.Lastname) AS ParentName
from cteUsers
left join Users as p
on cteUsers.ParentId=p.UserId
;