简体   繁体   English

T-SQL递归函数-具有ParentID的CTE

[英]T-SQL Recursive Function - CTE with ParentID

I am trying to write a query in SQL Server to extract all of the information linked to a Task but I've hit a bit of a problem. 我正在尝试在SQL Server中编写查询以提取链接到任务的所有信息,但遇到了一些问题。 What I want to happen is when I pass in a parameter (@TaskID) and for that to return task information for that ID and also any sub-task information related to that ID. 我想发生的是当我传入参数(@TaskID)并为此返回该ID的任务信息以及与该ID相关的任何子任务信息时。

The problem is that once you reach the first sub-task it effectively loses its link to the overall Parent TaskID. 问题是,一旦您到达第一个子任务,它实际上就会失去与整个父任务ID的链接。 For example: TaskID (3) is ultimately linked to TaskID (1) but because it's a sub-task of TaskID (2) there is no way to check unless I join the Parent (TaskID 1) to TaskID 2 and then to TaskID 3. 例如:TaskID(3)最终链接到TaskID(1),但是由于它是TaskID(2)的子任务,因此除非我将Parent(TaskID 1)加入TaskID 2,然后再加入TaskID 3,否则无法进行检查。 。

What we would like to do is have an infinite number of sub-tasks but that would require too many joins. 我们想做的是拥有无限数量的子任务,但这将需要太多的联接。

I was wondering if there was a better way? 我想知道是否有更好的方法?

Table structure or query wise. 表结构或查询明智。

Sample Table Structure 样本表结构 表结构

WITH cte AS (
SELECT
    t.TaskID
    ,t.Title
    ,t.ParentID
    ,CAST(t.TaskID AS NVARCHAR(MAX)) [Path]
FROM 
    tasks.Tasks t
WHERE 
    t.TaskID = 3

UNION ALL

SELECT
    c.ParentID  
    ,c.Title
    ,t.ParentID
    ,c.[Path] + '->' + CAST(t.TaskID AS NVARCHAR(MAX))
FROM
    tasks.Tasks t
    INNER JOIN cte c on c.ParentID = t.TaskID
)

SELECT 
    cte.TaskID
    ,cte.Title
    ,cte.[Path]
FROM 
    cte
WHERE 
    cte.ParentID IS NULL

This gives the correct result but I should really pass the TaskID without the ParentID as this would be the top level. 这样可以得出正确的结果,但是我应该真正通过TaskID而不使用ParentID,因为这将是最高级别。 So instead of t.TaskID = 3 in my code block, I would want to pass 1. I'll have a play... 因此,我想传递1,而不是代码块中的t.TaskID = 3。

This worked for me. 这对我有用。 Passing '1' as the TaskID will now allow me to see all the sub-tasks related to it (in the example 2 & 3). 现在将“ 1”作为TaskID传递使我可以查看与其相关的所有子任务(在示例2和3中)。

WITH cte AS 
(
SELECT 
    t.TaskID
    ,t.Title
    ,t.ParentID 
    ,CONVERT(VARCHAR(MAX),'') AS [Path]
FROM 
    tasks.Tasks t
WHERE 
    t.ParentID IS NULL
    AND t.TaskID = @TaskID

UNION ALL

SELECT 
    sub.TaskID 
    ,sub.Title 
    ,sub.ParentID 
    ,cte.[Path] + '->' + CONVERT(VARCHAR(MAX),sub.TaskID) AS [Path]
FROM 
    tasks.Tasks sub
    INNER JOIN cte ON cte.TaskID = sub.ParentID
)

SELECT 
    cte.TaskID
    ,cte.Title
    ,cte.ParentID
    ,CONVERT(VARCHAR(MAX),@TaskID) + cte.[Path] AS [Path]
FROM 
    cte

Thanks for the help everyone 谢谢大家的帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM