如何在使用CTE时设置订单?

时间:2016-12-26 16:05:49

标签: sql-server common-table-expression

我有一个包含2列的表(id,childId)。数据如下:

  • 1,2
  • 3,4
  • 2,null
  • 4,null

我正在使用CTE以便获取子记录:

DECLARE @id TABLE (id int);
INSERT INTO @id SELECT 1;
INSERT INTO @id SELECT 3;

WITH cte AS
(
    SELECT id, childId
    FROM mytable
    WHERE 
        id IN (SELECT id FROM @id)
    UNION ALL
    SELECT b.id, b.childId
    FROM mytable b
    INNER JOIN cte 
        ON b.id = cte.childId
)
SELECT * FROM cte

结果总是回归:

  • 1,2
  • 3,4
  • 4,null
  • 2,null

但我需要结果如下:

  • 1,2
  • 2,null
  • 3,4,
  • 4,null

也就是说,首先,锚记录每个锚记录的递归sql的记录。

这可能吗?

2 个答案:

答案 0 :(得分:1)

在锚点查询中添加静态值。然后在递归部分添加一个大于锚查询的静态值的静态值。现在使用Order by

中的静态值

试试这个

WITH cte AS
(
    SELECT 0 as rn, id, childId
    FROM mytable
    WHERE 
        id IN (SELECT id FROM @id)
    UNION ALL
    SELECT 1 as rn,b.id, b.childId
    FROM mytable b
    INNER JOIN cte 
        ON b.id = cte.childId
)
SELECT * FROM cte
Order by rn,id

另请考虑添加option(Maxrecursion N)。默认情况下,它只会进行100递归

答案 1 :(得分:1)

通过添加Seq,结果将以正确的顺序/嵌套显示

DECLARE @id TABLE (id int);
INSERT INTO @id SELECT 1;
INSERT INTO @id SELECT 3;

WITH cte AS
(
    SELECT id, childId
          ,Seq  = cast(100000+Row_Number() over (Order by id) as varchar(500))
    FROM mytable
    WHERE 
        id IN (SELECT id FROM @id)
    UNION ALL
    SELECT b.id, b.childId
          ,Seq  = cast(concat(cte.Seq,'.',100000+Row_Number() over (Order by b.id)) as varchar(500))
    FROM mytable b
    INNER JOIN cte 
        ON b.id = cte.childId
)
SELECT * FROM cte 
Order By Seq