构造这个数据,以便它可以通过递归cte读取? (SQL Server)

时间:2016-05-20 15:48:33

标签: sql-server recursion

我需要一个查询,根据下面的信息返回表的祖先。源表目前按照描述进行结构化,并且递归CTE不起作用。我似乎无法理解源表应该如何构建以使CTE工作。

有人可以建议一个源表结构和查询将返回以下内容吗?如果有比递归更好的方法,那也是有效的。

源表包含来自我的SQL Server数据库的反映数据沿袭的信息。为了生成表T4,您执行过程P1,P2和P3。

有一条规则,即一张桌子只能有一个父母'过程,但一个过程可以构建多个表。因此P3可以构建T3和T4,但T3只能通过一个过程(P3)构建。

实施例

如果查询已输入' T4',则应返回此信息:

referencing_ancestor    referenced_ancestors    
P3                      T2, LOOKUP_TABLE
P2                      T1
P1                      staging

这是当前结构中的源信息,但结构可能会发生变化。我只需要给定表的祖先信息。

declare @Dependencies table
(
    id int identity(1,1),
    referencing_name nvarchar(50) NOT NULL,
    referenced_name nvarchar(50) NULL,
    select_from int NULL,
    insert_to int NULL
) 

insert into @Dependencies
select 'P1', 'staging', 1, 0    --> P1 selects data from staging
union all
select 'P1', 'T1', 0, 1         --> P1 populates T1
union all
select 'P2', 'T1', 1, 0         --> P2 selects data from T1
union all
select 'P2', 'T2', 0, 1         --> P2 populates T2
union all
select 'P3', 'LOOKUP_TABLE', 1, 0  --> P3 selects data from LOOKUP_TABLE
union all
select 'P3', 'T2', 1, 0         --> P3 selects data from T2
union all
select 'P3', 'T3', 0, 1         --> P3 populates  T3
union all
select 'P3', 'T4', 0, 1         --> P3 populates T4 

此查询无效,无法确定如何修复:

 ;with ancestors as 
    (
        select referencing_name, referenced_name, Level = 0
        from @Dependencies
        where referenced_name = 'T4'

        union all

        select d.referencing_name, d.referenced_name, Level + 1
        from @Dependencies d
        inner join ancestors a on a.referenced_name = d.referenced_name
        where insert_to = 0
    )

    select * from ancestors  

1 个答案:

答案 0 :(得分:1)

我想你可能想要建立一些"等级" @Dependencies表本身的列,但在这个例子中,我只是通过DENSE_RANK函数中的referencing_name排序。

;WITH ancestors AS (
    SELECT *, DENSE_RANK() OVER (ORDER BY referencing_name) AS tbl_level
    FROM    @Dependencies
)
SELECT  a2.* 
FROM    ancestors a1
JOIN    ancestors a2 ON a2.tbl_level <= a1.tbl_level
WHERE   a1.referenced_name = 'T4'
AND     a2.insert_to = 0 
ORDER BY tbl_level DESC