复杂案例陈述T-SQL - 具有层次遍历.

gop*_*ath 3 sql t-sql sql-server case hierarchy

我试图CASE在分层数据集上写一个复杂的语句.

这是包含样本数据的表:

Level  Parent     Child       IsDirector
----------------------------------------
0      NULL       SteveJobs     NO
1      SteveJobs  TimCook       YES
2      TimCook    Greg          NO
3      Greg       Mark          NO
4      Mark       Jack          NO
4      Mark       Kim           NO
4      Mark       Tyler         NO
4      Mark       Emma          NO
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个SQL查询来列出所有人的导演.在上面的示例中,这是SteveJobs担任首席执行官的IT团队的一部分,因此他不是董事.TimCook是董事,董事是Greg经理.经理是员工.

所以我想写一个查询来选择所有人和Director列中的相关Director Name,条件是如果它是CEO,那么它应该是NULL.

在我的现实生活数据中,有几位CEO,每位CEO都有多位董事,每位董事都有多名经理.这对我来说真的很复杂.

如果我写一个select*,结果应该是这样的.

Parent     Child        Director  IsDirector
------------------------------------
NULL       SteveJobs    NULL      NO
SteveJobs  TimCook      TimCook   YES
TimCook    Greg         TimCook   NO
Greg       Mark         TimCook   NO
Mark       Jack         TimCook   NO
Mark       Kim          TimCook   NO
Mark       Tyler        TimCook   NO
Mark       Emma         TimCook   NO
Run Code Online (Sandbox Code Playgroud)

这是我为实现这一目的而编写的查询,但它不能按预期工作.

SELECT 
    A.Parent, A.Child,
    CASE A.IsDirector 
        WHEN 'YES' 
           THEN A.Child
        WHEN 'NO' 
           THEN CASE 
                   WHEN (A.IsDirector = 'NO' AND A.Parent IS NOT NULL) 
                      THEN A.Parent
                      ELSE (SELECT  
                                CASE WHEN B.IsDirector = 'YES' 
                                        THEN B.Parent
                                END AS Director
                            FROM @Org B 
                            WHERE B.Child = A.Parent) 
                END 
    END AS Director,
    A.IsDirector
FROM
    @Org A
Run Code Online (Sandbox Code Playgroud)

Joh*_*tti 5

这可以在递归cte的帮助下生成

Declare @YourTable table (Level int,Parent varchar(50),Child varchar(50),IsDirector varchar(50))
Insert into @YourTable values
(0,NULL,'SteveJobs','NO'),
(1,'SteveJobs','TimCook','YES'),
(2,'TimCook','Greg','NO'),
(3,'Greg','Mark','NO'),
(4,'Mark','Jack','NO'),
(4,'Mark','Kim','NO'),
(4,'Mark','Tyler','NO'),
(4,'Mark','Emma','NO')

;with cteP as (
      Select Parent
            ,Child
            ,Director = case when IsDirector='YES' then CHILD else NULL end 
            ,IsDirector
      From   @YourTable 
      Where  Parent is null
      Union  All
      Select r.Parent
            ,r.Child
            ,Director = case when r.IsDirector='YES' then r.CHILD else p.Director end
            ,r.IsDirector
      From   @YourTable r
      Join   cteP p on r.Parent = p.Child)
Select * from cteP
Run Code Online (Sandbox Code Playgroud)

返回

在此输入图像描述