我已经盯着这段代码看了太久,试图找出为什么我的最终查询会返回意外的结果。
非常感谢任何帮助。提前谢谢。
给出以下代码(在SQL Server 2008 R2上运行):
USE tempdb; DECLARE @emp--loyee TABLE ( EmployeeID int NOT NULL ,EmployeeName nvarchar(50) NOT NULL PRIMARY KEY(EmployeeID) ) INSERT INTO @emp SELECT 1,'Fred' UNION SELECT 2,'Mary' UNION SELECT 3,'Joe' UNION SELECT 4,'Bill' DECLARE @grp TABLE ( GroupID int NOT NULL ,GroupName nvarchar(50) PRIMARY KEY(GroupID) ) INSERT INTO @grp SELECT 1,'Group 1' UNION SELECT 2,'Group 2' UNION SELECT 3,'Group 3' DECLARE @empgrp TABLE ( EmployeeID int NOT NULL ,GroupID int NOT NULL PRIMARY KEY (EmployeeID,GroupID) ) INSERT INTO @empgrp SELECT 1,1 UNION SELECT 2,1 UNION SELECT 3,1 UNION SELECT 4,2 DECLARE @grpgrp TABLE ( GroupID int NOT NULL ,ParentGroupID int ,UNIQUE CLUSTERED(GroupID,ParentGroupID) ) INSERT INTO @grpgrp SELECT 1,2 UNION SELECT 2,3; WITH AllEmpGroups (EmployeeID,GroupID,RootGroupID) AS ( SELECT CAST(NULL as int) as EmployeeID,pgrp.GroupID,pgrp.ParentGroupID FROM @grpgrp pgrp LEFT JOIN @grpgrp ggrp ON pgrp.ParentGroupID = ggrp.GroupID UNION ALL SELECT e.EmployeeID,eg.GroupID,aeg.RootGroupID FROM @emp e JOIN @empgrp eg ON e.EmployeeID = eg.EmployeeID JOIN @grpgrp ggrp ON eg.GroupID = ggrp.GroupID JOIN AllEmpGroups aeg ON aeg.GroupID = ggrp.ParentGroupID ) SELECT EmployeeID,GroupID,RootGroupID FROM AllEmpGroups
我得到的是:
+------------+---------+-------------+ | EmployeeID | GroupID | RootGroupID | +------------+---------+-------------+ | NULL | 1 | 2 | | NULL | 2 | 3 | | 1 | 1 | 3 | | 2 | 1 | 3 | | 3 | 1 | 3 | +------------+---------+-------------+
我期望/想要得到的是:
+------------+---------+-------------+ | EmployeeID | GroupID | RootGroupID | +------------+---------+-------------+ | NULL | 1 | 2 | | NULL | 2 | 3 | | 4 | 2 | 3 | | 1 | 1 | 3 | | 2 | 1 | 3 | | 3 | 1 | 3 | +------------+---------+-------------+
总而言之,我想要在给定根组下面的所有员工的完整递归堆栈,每行都有根组ID。
我错过了什么?
答案 0 :(得分:2)
首先:
@grpgrp
中的根节点需要一行,其值为3, null
union all
之前的部分)需要是祖先第一次递归的根节点(3, null
)。...
INSERT INTO @grpgrp
SELECT 1,2
UNION all
SELECT 2,3
UNION all
select 3, null;
WITH AllEmpGroups (EmployeeID,GroupID,RootGroupID)
AS
(
SELECT CAST(NULL as int) as EmployeeID,pgrp.GroupID, ParentGroupID = pgrp.GroupID
FROM @grpgrp pgrp LEFT JOIN @grpgrp ggrp
ON pgrp.ParentGroupID = ggrp.GroupID
where pgrp.ParentGroupId is null
UNION ALL
SELECT e.EmployeeID,eg.GroupID,aeg.RootGroupID
FROM @emp e JOIN @empgrp eg
ON e.EmployeeID = eg.EmployeeID
JOIN @grpgrp ggrp
ON eg.GroupID = ggrp.GroupID
JOIN AllEmpGroups aeg
ON aeg.GroupID = ggrp.ParentGroupID
)
SELECT EmployeeID,GroupID,RootGroupID
FROM AllEmpGroups
rextester演示:http://rextester.com/CBWY80387
返回:
+------------+---------+-------------+
| EmployeeID | GroupID | RootGroupID |
+------------+---------+-------------+
| NULL | 3 | 3 |
| 4 | 2 | 3 |
| 1 | 1 | 3 |
| 2 | 1 | 3 |
| 3 | 1 | 3 |
+------------+---------+-------------+
除此之外,我将首先构建组层次结构,然后像这样加入员工:
WITH AllEmpGroups (GroupID,ParentGroupID,RootGroupID)
AS
(
SELECT pgrp.GroupID, pgrp.ParentGroupID, RootGroupId = GroupID
FROM @grpgrp pgrp
where pgrp.ParentGroupId is null
UNION ALL
SELECT ggrp.GroupID,ggrp.ParentGroupID,aeg.RootGroupID
FROM @grpgrp ggrp
inner JOIN AllEmpGroups aeg
ON aeg.GroupID = ggrp.ParentGroupID
)
SELECT eg.EmployeeID,aeg.*
FROM AllEmpGroups aeg
left JOIN @empgrp eg
ON eg.GroupID = aeg.GroupID
rextester演示:http://rextester.com/FAK76354
返回:
+------------+---------+---------------+-------------+
| EmployeeID | GroupID | ParentGroupID | RootGroupID |
+------------+---------+---------------+-------------+
| NULL | 3 | NULL | 3 |
| 4 | 2 | 3 | 3 |
| 1 | 1 | 2 | 3 |
| 2 | 1 | 2 | 3 |
| 3 | 1 | 2 | 3 |
+------------+---------+---------------+-------------+
答案 1 :(得分:2)
从
开始WITH AllGroups (RootGroupID,GroupID,ParentGroupID, level)
AS
(
SELECT GroupID RootGroupID, GroupID, Cast(NULL as int) ParentGroupID, 0 level
FROM @grp g
WHERE NOT EXISTS (SELECT 1 FROM @grpgrp gg WHERE gg.GroupID = g.GroupID)
UNION ALL
SELECT ag.RootGroupID, gg.GroupID, gg.ParentGroupID, level+1
FROM @grpgrp gg
JOIN AllGroups ag
ON ag.GroupID = gg.ParentGroupID
)
SELECT EmployeeID, ag.GroupID, ParentGroupID, RootGroupID
FROM AllGroups ag
LEFT JOIN @empgrp eg ON eg.GroupID = ag.GroupID
ORDER BY RootGroupID, level, ParentGroupID, GroupID;
不确定为什么需要这一行:
| NULL | 2 | 3 |