对于基于经理的每位员工,应该取消部门。
如果经理的部门是null
,那么它应该取回经理的部门。这个层次结构循环应该继续,直到它拿起一些部门。请查看附件中的数据或以下内容。
EmpName EmpId MgrName MgrId Dept
A 1 D 4
B 2 D 4
C 3 D 4
D 4 E 5
E 5 F 6
F 6 G 7
G 7 Q 17 CSC
H 8 I 9
I 9 Q 17 MECH
J 10 O 15
K 11 O 15
L 12 O 15
M 13 O 15
N 14 O 15
O 15 Q 17 EEE
P 16 Q 17
Q 17 IT
答案 0 :(得分:0)
您可以将其余数据添加到此处并尝试一下:
DECLARE @table AS TABLE (EmpName NVARCHAR(1)
,EmpId INT
,MGRName NVARCHAR(1)
,MgrID INT
,Dept NVARCHAR(4)
)
INSERT INTO @table
(EmpName, EmpId, MGRName, MgrID, Dept)
VALUES ('A', 1, 'D', 4, '')
, ('B', 2, 'D', 4, '')
, ('C', 3, 'D', 4, '')
, ('D', 4, 'E', 5, '')
, ('E', 5, 'F', 6, '')
, ('F', 6, 'G', 7, '')
, ('G', 7, 'Q', 17, 'CSC')
, ('Q', 2, '', NULL, 'IT');
WITH cte
AS (SELECT EmpName
, EmpId
, MGRName
, MgrID
, Dept
FROM @table t
UNION ALL
SELECT c.EmpName
, c.EmpId
, t2.MGRName
, t2.MgrID
, t2.Dept
FROM @table t2
JOIN cte C ON c.MGRId = t2.EmpId
AND c.Dept = ''
)
SELECT *
FROM cte
WHERE Dept <> ''
ORDER BY EMpName
对于将来的问题,如果您提供表格声明和样本数据作为我们可以剪切和粘贴的内容,您可能会得到更多回复。
答案 1 :(得分:0)
您可以直接从递归查询更新。
;with RCTE as
(
select EmpId as RootEmpId, 0 as Lvl, EmpId, MgrID, Dept
from Employee
where Dept is null
union all
select r.RootEmpId, r.Lvl + 1, e.EmpId, e.MgrID, e.Dept
from RCTE r
join Employee e on e.EmpId = r.MgrID
where r.Dept is null
)
update e
set Dept = r.Dept
from Employee e
join RCTE r on (e.EmpId = r.RootEmpId and r.Dept is not null)
where e.Dept is null;
示例测试代码段
declare @Employee table (EmpId int primary key, EmpName nvarchar(100), MgrID int, Dept NVARCHAR(4));
insert into @Employee (EmpName, EmpId, MgrID, Dept) VALUES
('A',1,4,null)
,('B',2,4,null)
,('C',3,4,null)
,('D',4,5,null)
,('E',5,6,null)
,('F',6,7,null)
,('G',7,17,'CSC')
,('H',8,9,null)
,('I',9,17,'MECH')
,('J',10,15,null)
,('K',11,15,null)
,('L',12,15,null)
,('M',13,15,null)
,('N',14,15,null)
,('O',15,17,'EEE')
,('P',16,17,null)
,('Q',17,null,'IT')
;
;with RCTE as
(
select EmpId as RootEmpId, 0 as Lvl, EmpId, MgrID, Dept
from @Employee
where Dept is null
union all
select r.RootEmpId, r.Lvl + 1, e.EmpId, e.MgrID, e.Dept
from RCTE r
join @Employee e on e.EmpId = r.MgrID
where r.Dept is null
)
update e
set Dept = r.Dept
from @Employee e
join RCTE r on (e.EmpId = r.RootEmpId and r.Dept is not null)
where e.Dept is null;
select
e.EmpName, e.EmpId, e.MgrID, e.Dept,
m.EmpName as MgrName, m.Dept as MgrDept
from @Employee e
join @Employee m on (m.EmpId = e.MgrID)
order by EmpId;
旁注:本着normalization的精神,维持一个部门表会更常见。然后只需将DepartmentID外键存储在Customer表中。而不是可以改变的部门名称。
答案 2 :(得分:0)
我认为这样做会 您通过包含mgr名称
来对数据进行非格式化declare @t table (Emp char, Id int, MgrId int, Dept varchar(10))
insert @t values
('A', 1, 4, null),
('B', 2, 4, null),
('C', 3, 4, null),
('D', 4, 5, null),
('E', 5, 6, null),
('F', 6, 7, null),
('G', 7, 17, 'CSC'),
('H', 8, 9, null),
('I', 9, 17, 'MCH'),
('J', 10, 15, null),
('K', 11, 15, null),
('L', 12, 15, null),
('M', 13, 15, null),
('N', 14, 15, null),
('O', 15, 17, 'EEE'),
('P', 16, 17, null),
('Q', 17, null, 'IT');
with cte as
( select t1.Id, t1.emp, t1.MgrId, isnull(t1.Dept, t2.Dept) as Dept, t2.Emp as 'mgr', t2.MgrId as nextMgr
from @t t1
left join @t t2
on t2.Id = t1.MgrId
--where not exists ( select * from @t t where t.MgrId = t1.Id )
union all
select t1.Id, t1.emp, t1.MgrId, t2.Dept, t1.mgr, t2.MgrId as nextMgr
from cte t1
join @t t2
on t2.Id = t1.nextMgr
and t1.Dept is null
)
select *
from cte
where Dept is not null
order by id
Id emp MgrId Dept mgr nextMgr
----------- ---- ----------- ---------- ---- -----------
1 A 4 CSC D 17
2 B 4 CSC D 17
3 C 4 CSC D 17
4 D 5 CSC E 17
5 E 6 CSC F 17
6 F 7 CSC G 17
7 G 17 CSC Q NULL
8 H 9 MCH I 17
9 I 17 MCH Q NULL
10 J 15 EEE O 17
11 K 15 EEE O 17
12 L 15 EEE O 17
13 M 15 EEE O 17
14 N 15 EEE O 17
15 O 17 EEE Q NULL
16 P 17 IT Q NULL
17 Q NULL IT NULL NULL