如何从CTE获取不同的依赖列表

时间:2012-06-08 14:26:03

标签: sql-server tsql sql-server-2008-r2

我有一个表task_dependency,如下所示

task_id   depend_task_id
-------------------------
1             NULL
2             NULL
3             1
4             2
4             1
5             4
5             3

我尝试运行查询以在每个任务上获得不同的任务依赖列表(包括任务本身)。

预期输出(任务列表顺序无关紧要):

task_id depend_task_list
-----------------------------------------------
1       1;
2       2;
3       1;3
4       1;2;4
5       1;2;3;4;5

到目前为止我有什么

DECLARE @t TABLE (task_id INT, depend_task_id INT)

INSERT INTO @t VALUES (1, NULL),(2,NULL),(3,1),(4,2),(4,1),(5,4),(5,3)

;WITH AllDependency (task_id,depend_task_list)
AS(  
   SELECT 
     task_id,
     depend_task_list=CAST(task_id AS VARCHAR(4000))
   FROM @t
   WHERE depend_task_id IS NULL
 UNION ALL
   SELECT 
     t.task_id,
     depend_task_list= CAST(CAST(t.task_id AS VARCHAR(10)) + ';' + depend_task_list AS VARCHAR(4000))
   FROM @t t
   INNER JOIN AllDependency  AS d
        ON d.task_id = t.depend_task_id
) 
SELECT 
    task_id,
    (SELECT depend_task_list + ';' FROM AllDependency d2 WHERE d.task_id = d2.task_id FOR XML PATH('')) AS depend_task_list
FROM AllDependency d
GROUP BY task_id
ORDER BY task_id

当前输出:

task_id depend_task_list
-----------------------------------------
1           1;
2           2;
3           3;1;
4           4;2;4;1;
5           5;4;2;5;4;1;5;3;1;

问题: 如何在不使用Cursor的情况下获得不同的任务依赖列表?

SQLFiddle链接http://sqlfiddle.com/#!3/4c034/2

提前感谢您的任何帮助。

1 个答案:

答案 0 :(得分:3)

好的,试试这个查询,看看是否有帮助:

DECLARE @t TABLE (task_id INT, depend_task_id INT)

INSERT INTO @t VALUES (1, NULL),(2,NULL),(3,1),(4,2),(4,1),(5,4),(5,3)

;WITH CTE AS
(
    SELECT *
    FROM @t
    UNION ALL
    SELECT A.task_id, B.depend_task_id
    FROM CTE A
    INNER JOIN @t B
    ON A.depend_task_id = B.task_id
    --WHERE B.depend_task_id IS NOT NULL
), CTE2 AS 
(
    SELECT DISTINCT task_id, ISNULL(depend_task_id,task_id) depend_task_id
    FROM CTE
)
SELECT  t1.task_id, 
        STUFF( (SELECT ';' + CAST(t2.depend_task_id AS VARCHAR(5))
                FROM CTE2 t2
                WHERE t2.task_id = t1.task_id
                ORDER BY depend_task_id
                FOR XML PATH('')),1,1,'') AS depend_task_list
FROM CTE2 t1
GROUP BY task_id

Here是对sqlfiddle的测试。