具有交替表的递归CTE

时间:2014-06-13 14:03:01

标签: sql sql-server-2008 common-table-expression recursive-query self-referencing-table

我创建了一个SQL小提琴here

基本上,我有3个表BaseTableFilesLinkingTable

Files表有3列:PKBaseTableIdRecursiveId(ChildId)。 我想要做的是找到给BaseTableId的所有孩子(即ParentId)。 棘手的部分是找到孩子的方式是这样的:

ParentIdBaseTable.BaseTableId)1并使用它在FileId表格中查找Files,然后使用FileId查找ChildId中的LinkingTable.RecursiveId LinkingTable,如果该记录存​​在,则使用RecursiveId中的LinkingTable查找下一个FileId Files表等等。

到目前为止,这是我的CTE:

with CTE as
(
    select lt.FileId, lt.RecursiveId, 0 as [level],
        bt.BaseTableId
    from BaseTable bt
    join Files f
    on bt.BaseTableId = f.BaseTableId
    join LinkingTable lt
    on f.FileId = lt.FileId
    where bt.BaseTableId = @Id
    UNION ALL
    select rlt.FileId, rlt.RecursiveId, [level] + 1 as [level],
        CTE.BaseTableId
    from CTE --??? and this is where I get lost
...
)

BaseTableId = 1的正确输出应为:

FileId|RecursiveId|level|BaseTableId
  1        1         0        1
  3        2         1        1
  4        3         2        1

表关系

Table Relationship

1 个答案:

答案 0 :(得分:1)

这是一个我认为符合您标准的递归示例。我在结果集中添加了ParentId,对于根/基本文件,它将为NULL,因为它没有父文件。

declare @BaseTableId int;
set @BaseTableId  = 1;

; WITH cteRecursive as (
    --anchor/root parent file
    SELECT null as ParentFileId
        , f.FileId as ChildFileID
        , lt.RecursiveId 
        , 0 as [level]
        , bt.BaseTableId
    FROM BaseTable bt
        INNER JOIN Files f
            on bt.BaseTableId = f.BaseTableId
        INNER JOIN LinkingTable lt
            on f.FileId = lt.FileId
    WHERE bt.BaseTableId = @BaseTableId 

    UNION ALL 

    SELECT cte.ChildFileID as ParentFileID 
        , f.FileId as ChildFileID
        , lt.RecursiveId
        , cte.level + 1 as [level]
        , cte.BaseTableId
    FROM cteRecursive cte
        INNER JOIN Files f on cte.RecursiveId = f.RecursiveId
        INNER JOIN LinkingTable lt ON lt.FileId = f.FileId
)
SELECT * 
FROM cteRecursive
;

@BaseTableID = 1的结果:

ParentFileId ChildFileID RecursiveId level       BaseTableId
------------ ----------- ----------- ----------- -----------
NULL         1           1           0           1
1            3           2           1           1
3            4           3           2           1

@BaseTableID = 2的结果:

ParentFileId ChildFileID RecursiveId level       BaseTableId
------------ ----------- ----------- ----------- -----------
NULL         2           1           0           2
NULL         2           4           0           2
2            6           5           1           2
6            7           6           2           2
2            3           2           1           2
3            4           3           2           2