Ano*_*use 6 sql t-sql recursion common-table-expression
嗨说我有一张桌子:
Person:
PersonId
Name
ManagerId
Run Code Online (Sandbox Code Playgroud)
所以ManagerId是一个回复给另一个人的参考.
所以数据库中可能有人:
1
Bob
null
2
Steve
1
3
Tim
2
Run Code Online (Sandbox Code Playgroud)
所以鲍勃是史蒂夫的经理而史蒂夫是蒂姆的经理.
所以我想要做的就是编写一个查询,让Bob管理下的所有人.直接或间接.所以我想要得到史蒂夫和蒂姆.在同一条线上.
如果我写:
select * from Person
where ManagerId = 1 I would get only Steve.
Run Code Online (Sandbox Code Playgroud)
我怎么写它所以我直接或间接地让每个人都在Bob下?
您可以使用公用表表达式(CTE)来解决此问题.正如安德烈指出的那样,CTE可以用于递归(参见Andrei在其帖子中包含的优秀参考文献).假设你有一张表如下:
create table Person
(
PersonId int primary key,
Name varchar(25),
ManagerId int foreign Key references Person(PersonId)
)
Run Code Online (Sandbox Code Playgroud)
然后让我们将以下数据插入表中:
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)
Run Code Online (Sandbox Code Playgroud)
然后我们想要一个查询,它将返回所有直接或间接向Bob报告的人,这些人将是Steve,Tim和John.我们不想归还詹姆斯和鲍勃,因为他们向詹姆斯报告,因为他们向任何人或乔报告.这可以通过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
Run Code Online (Sandbox Code Playgroud)
此查询返回正确的结果:
PersonId Name ManagerId
----------- ------------------------- -----------
2 Steve 1
3 Tim 2
4 John 3
Run Code Online (Sandbox Code Playgroud)
编辑:假设OP使用的是SQL Server 2005或更高版本,则此答案有效.我不知道这种语法在MySQL或Oracle中是否有效.