この問題を解決するには、共通テーブル式 (CTE) を使用できます。Andrei が指摘したように、CTE は再帰に使用できます (Andrei が投稿に含めた優れたリファレンスを参照してください)。次のようなテーブルがあるとします。
create table Person
(
PersonId int primary key,
Name varchar(25),
ManagerId int foreign Key references Person(PersonId)
)
次のデータをテーブルに挿入しましょう。
insert into Person (PersonId, Name, ManagerId) values
(1,'Bob', null),
(2, 'Steve',1),
(3, 'Tim', 2)
(4, 'John', 3),
(5, 'James', null),
(6, 'Joe', 5)
次に、Bob に直接的または間接的に報告する全員 (Steve、Tim、および John) を返すクエリが必要です。James と Bob は誰にも報告しないため、または Joe は James に報告するため、返したくありません。これは、次のように CTE クエリで実行できます。
WITH Managers AS
(
--initialize
SELECT PersonId, Name, ManagerId
FROM Person WHERE ManagerId =1
UNION ALL
--recursion
SELECT p.PersonId, p.Name, p.ManagerId
FROM Person p INNER JOIN Managers m
ON p.ManagerId = m.PersonId
)
SELECT * FROM Managers
このクエリは正しい結果を返します。
PersonId Name ManagerId
----------- ------------------------- -----------
2 Steve 1
3 Tim 2
4 John 3
編集:この回答は、OP が SQL Server 2005 以降を使用していると仮定して有効です。この構文が MySQL または Oracle で有効かどうかはわかりません。