IF (Object_ID('Employee1') is Not Null)
Drop Table Employee1
Create Table Employee1(
EID int primary key,
Name varchar(50),
MID int references Employee1(EID)
)
Insert into Employee1 values
(1,'Peter',2),
(2,'Nancy',3),
(3,'Bob',null),
(4,'Philip',5),
(5,'Jason',3),
(6,'Gilbert',5)
给我开胃菜,所有经理经理的名字
下面是我为这个问题写的查询
select distinct
e1.eid,
e1.name,
e1.mid
from employee1 e1
inner join employee1 e2 on e1.eid = e2.mid
inner join employee1 e3 on e3.mid = e2.eid
但是我找不到这个查询是如何工作的。它给了我正确的答案,但是,我怎么不知道。
有人能解释一下这个查询是如何一步一步地执行的吗?提前谢谢。
发布于 2020-11-24 07:04:16
我最初的想法是,这是上升的链子,它看起来是向下的链,经过更仔细的审查。因此,每个经理必须至少有两个级别的下属,然后才能返回该经理。如果他们没有至少两个级别;经理将不会被返回。
因此,在中间假设MID是managerID时,查询每次连接到managerID表2次。因为每个联接都是内部联接,因此只有有员工的经理和有员工的员工才会返回。这意味着只有低于2级员工的经理才会返回;而在那些只有不同员工的管理人员中,才会返回。
分解它:
第一次加入将返回所有经理和他们的员工。第二次加入将返回所有经理和他们的员工。
因此,结果将是主employee表中的所有经理的不同列表,但只有当他们有员工时,而且由于内部联接的性质,他们的员工只有在关联表中存在记录时才返回记录。
还有其他方法可以使用递归的CTE来实现这一点,而不必为您想要跟踪的每个级别使用单独的联接;从而消除了为每个所需级别添加联接的需要。
With CTE AS (
SELECT eid EID , name NAME , mid MID, 1 as Depth
FROM EMPLOYEE1
WHERE MID is not null
UNION ALL
--This union all is part of the recursion magic
SELECT E1.eid,e1.name,e1.mid, Depth+1
FROM Employee1 E1
--This is where it gets really weird. We're doing a join to the CTE itself from within the CTE... That's recursion.
INNER JOIN CTE E2
on E2.MID=E1.EID
)
SELECT Distinct * FROM CTE
WHERE DEPTH = 3
;
其结果是:
+----+-----+------+------+-------+
| | EID | NAME | MID | Depth |
+----+-----+------+------+-------+
| 1 | 3 | Bob | NULL | 3 |
+----+-----+------+------+-------+
https://stackoverflow.com/questions/64989062
复制