2016-12-26 27 views
2

我有一个2列(id,childId)表。数据如下:如何在使用CTE时设置订单?

  • 1,2
  • 3,4
  • 2,空
  • 4,空

我使用的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,空
  • 2,空

但我需要的结果是这样的:

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

即,第一锚定记录,则记录为每个锚记录递归SQL。

这可能吗?

回答

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

通过增加一个序列,结果将显示在正确的顺序/嵌套

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 
+0

我没有落后'100000'在逻辑'Row_number'是真的需要吗?我不这么认为 –

+0

@Prdp序列一致性。 1,10,2 vs 10001,10002,10010 –

+0

@Prdp模糊点:),但我用这个字符串来建立范围键http://stackoverflow.com/questions/41250197/sql-query-order-by-top-类别遵循逐子类别/ 41250489#41250489 –