【问题标题】:A real recursion with CTE?CTE 的真正递归?
【发布时间】:2012-07-23 02:22:30
【问题描述】:

我今天下午才发现 CTE,在享受了 2 小时后,我意识到它们并没有像我们在任何其他语言中学到的那样执行常见的递归。

我的意思是,我总是将递归视为树搜索。所以我期待 CTE 一直到它发现的第一片叶子,但没有。他分层工作。它从头部开始,然后是所有分支,然后是所有子分支,等等……然后是叶子。

有没有办法让它以不同的方式搜索?也许我错过了什么…… 我在 SQL Server 2005 上工作(非,我不能为 2008 年更改)

为了清楚起见,我不想:

  1. 团队1
  2. 团队2
  3. 团队3
  4. team1-1
  5. team3-1
  6. team1-2

但是

  1. 团队1
  2. team1-1
  3. team1-2
  4. 团队2
  5. 团队3
  6. team3-1

谢谢

【问题讨论】:

  • 我想到了一个 ORDER BY 子句。除非您指定,否则 CTE 不会改变您无法保证任何特定订单的事实。

标签: tsql recursion common-table-expression


【解决方案1】:

您可以在进行递归时构建一个列进行排序。

类似这样的:

declare @t table
(
  ID int,
  ParentID int,
  Name varchar(10)
);

insert into @T values
(1, null, 'team1'),
(2, null, 'team2'),
(3, null, 'team3'),
(4, 1, 'team1-1'),
(5, 1, 'team1-2'),
(6, 3, 'team3-1');

with C as
(
  select T.ID,
         T.ParentID,
         T.Name,
         cast(right(100000 + row_number() over(order by T.ID), 5) as varchar(max)) as Sort
  from @T as T
  where T.ParentID is null
  union all
  select T.ID,
         T.ParentID,
         T.Name,
         C.Sort+right(100000 + row_number() over(order by T.ID), 5)
  from @T as T
    inner join C
      on T.ParentID = C.ID
)
select *
from C
order by Sort

结果:

ID          ParentID    Name       Sort
----------- ----------- ---------- ------------
1           NULL        team1      00001
4           1           team1-1    0000100001
5           1           team1-2    0000100002
2           NULL        team2      00002
3           NULL        team3      00003
6           3           team3-1    0000300001

【讨论】:

  • 感谢您的提示。明天我会检查的。
  • @MikaelEriksson,我不知道 over 子句。太酷了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 2018-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
相关资源
最近更新 更多