bugfix> sql > 投稿
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

しかし、このクエリがどのように機能しているかがわかりませんでした。それは私に正しい答えを与えていますが、どうして私にはわかりません。

このクエリがどのように実行されているかを誰かが段階的に説明できますか? 前もって感謝します。

回答 1 件
  • 私の最初の考えは、これはチェーンを上っていくということでした。綿密な調査の結果、チェーンを下っていくようです。したがって、各マネージャーは、そのマネージャーが返還される前に、少なくとも2レベルの部下を持っている必要があります。少なくとも2つのレベルがない場合。マネージャーは返されません。

    したがって、MIDがmanagerIDであると仮定すると、クエリはMIDでemployee1テーブルに毎回2回結合します。各結合は内部結合であるため、従業員がいるマネージャーと従業員がいる従業員のみが返されます。これは、2レベル以上の従業員がいるマネージャーのみが返されることを意味します。そして、それらのうち、別個の従業員のみが返還されます。

    分解する:

    最初の参加 すべてのマネージャーとその従業員を返します。 2回目の結合では、すべてのマネージャーとその従業員が返されます

    したがって、結果はメインの従業員テーブルからのすべてのマネージャーの個別のリストになりますが、従業員がいる場合に限ります。内部結合の性質上、従業員には従業員がいます。レコードが関連付けられたテーブルに存在する場合にのみ返されます。

    追跡するレベルごとに個別の結合を使用する代わりに、再帰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 |
    +----+-----+------+------+-------+
    
    

あなたの答え