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)
私にEID、マネージャーのマネージャーであるすべての従業員の名前を取得します
以下は私がその質問のために書いた質問です
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
しかし、このクエリがどのように機能しているかがわかりませんでした。それは私に正しい答えを与えていますが、どうして私にはわかりません。
このクエリがどのように実行されているかを誰かが段階的に説明できますか? 前もって感謝します。
私の最初の考えは、これはチェーンを上っていくということでした。綿密な調査の結果、チェーンを下っていくようです。したがって、各マネージャーは、そのマネージャーが返還される前に、少なくとも2レベルの部下を持っている必要があります。少なくとも2つのレベルがない場合。マネージャーは返されません。
したがって、MIDがmanagerIDであると仮定すると、クエリはMIDでemployee1テーブルに毎回2回結合します。各結合は内部結合であるため、従業員がいるマネージャーと従業員がいる従業員のみが返されます。これは、2レベル以上の従業員がいるマネージャーのみが返されることを意味します。そして、それらのうち、別個の従業員のみが返還されます。
分解する:
最初の参加 すべてのマネージャーとその従業員を返します。 2回目の結合では、すべてのマネージャーとその従業員が返されます
したがって、結果はメインの従業員テーブルからのすべてのマネージャーの個別のリストになりますが、従業員がいる場合に限ります。内部結合の性質上、従業員には従業員がいます。レコードが関連付けられたテーブルに存在する場合にのみ返されます。
追跡するレベルごとに個別の結合を使用する代わりに、再帰CTEを使用してこれを行う方法は他にもあります。したがって、必要なレベルごとに結合を追加する必要がなくなります。
レクステスターの例
その結果: