在SQL Server CTE中添加where子句

时间:2018-08-27 06:52:14

标签: sql-server common-table-expression

我已经使用SQL Server CTE从我的架构为自引用表中选择数据

for($i=0;$i<count($arr);$i++)

每个CREATE TABLE BaseDomainTable ( [BaseModelId] INT, [Comments] NVARCHAR(100) NULL, [ParentModelId] INT NULL ) 都有注释,也可能没有父级,即任何模型都可以是第一个模型,并且任何模型都可以通过从任何父级开始来创建自己的新分支

ModelId

此插入后,1是我的基本父级,2是从1派生的,3和4是从2派生的。

要获取分层格式的数据,我添加了cte。

INSERT INTO BaseDomainTable ([BaseModelId],[Comments],[ParentModelId]) 
VALUES (1, 'Comments 1', NULL), (2, 'Comments 2', 1),
       (3, 'Comments for 3', 2), (4, 'Comments 4', 2)

然后我得到以下输出:

WITH ParentCTECheck (BaseModelId, Comments, ParentModelId) AS 
(
    SELECT 
        Parent.BaseModelId, Parent.Comments, Parent.ParentModelId 
    FROM
        BaseDomainTable Parent
    WHERE 
        Parent.ParentModelId IS NULL 
        AND Parent.Comments IS NOT NULL

    UNION ALL 

    SELECT 
        Derived.BaseModelId, Derived.Comments, Derived.ParentModelId  
    FROM
        BaseDomainTable Derived 
    JOIN
        ParentCTECheck ON ParentCTECheck.BaseModelId = Derived.ParentModelId
    WHERE 
        Derived.ParentModelId IS NOT NULL 
        AND Derived.Comments IS NOT NULL 
)
SELECT * 
FROM ParentCTECheck

我想更改它,以便如果我将BaseModelId传递为4,则cte将遍历4的循环,并在这种情况下跳过与3相关的所有数据,并返回4,2,1的数据。当我通过2时,应该同时跳过3和4并获得CTE遍历2的循环,即2,1

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

您必须自下而上遍历树:

;WITH ParentCTECheck AS (
   -- Anchor query: get leaf node
   SELECT BaseModelId, Comments, ParentModelId
   FROM BaseDomainTable
   WHERE BaseModelId = 4 -- <-- Id of leaf node

   UNION ALL

   -- Recursive query: go up the tree and get next level nodes.
   -- Recursion terminates as soon as the parent node is met.
   SELECT bt.BaseModelId, bt.Comments, bt.ParentModelId
   FROM BaseDomainTable AS bt
   JOIN ParentCTECheck AS ct ON bt.BaseModelId = ct.ParentModelId
)   
SELECT *
FROM ParentCTECheck

Demo here