【问题标题】:How to query for results recursively on the same table in SQL server如何在 SQL Server 的同一张表上递归查询结果
【发布时间】:2018-04-18 01:54:59
【问题描述】:

我有一个包含两列的表 - ID 和 AlternateID。 AlternateID 本身可能有一个 AlternateID,也在同一个表中捕获。

我的目标是构建一个表,其中具有 AlternateID 的 AlternateID 解析,直到它们不再具有 AlternateID。我该怎么做?

这是一些示例数据

源表是这样的

ID | AlternateID
-----------------
10 | 1
11 | 2
12 | 3
13 | 11
14 | 12
15 | 14

我的决赛桌应该是这样的

ID | FinalAlternateID
-----------------
10 | 1
11 | 2
12 | 3
13 | 2
14 | 3
15 | 3

目前尝试过的事情

  1. 编写了一个递归函数,它接受 id 并调用自身。这 一种作品,但对于我正在研究这种方法的数据集是 非常非常慢。
  2. 尝试编写递归 CTE,但无法 成功了,我得到了编译错误,只要我添加递归调用,它就不会被识别,不确定是什么问题。

这是 CTE 的代码(抱歉,由于某种原因无法格式化为堆栈中的代码)

with FinalAlternateIDs (ID, AlternateID, Level) as
(
-- start with ones that dont have an AlternateID
select T1.ID, T1.AlternateID, 0 as Level 
from InitialAlternateIDs T1
        left join InitialAlternateIDs T2 on (T1.AlternateID = T2.ID)
where T2.ID is NULL
union all
-- combine it with rows that have AlternateIDs in current result set
-- (exclude ones that are already in the result set)
select T1.ID, T3.AlternateID, (Level + 1) as Level 
from InitialAlternateIDs T1
        left join FinalAlternateIDs T2 on (T1.ID = T2.ID)
        join FinalAlternateIDs T3 on (T1.AlternateID = T3.ID)
where T2.ID is NULL
)
select * 
from FinalAlternateIDs

【问题讨论】:

  • 为什么不包括你的递归 CTE 代码?

标签: sql sql-server recursion common-table-expression


【解决方案1】:

您可以使用递归 CTE 来做到这一点:

with cte as (
      select id, alternateid, 1 as lev
      from t
      union all
      select cte.id, t.alternateid, lev + 1
      from cte join
           t
           on cte.alternateid = t.id
     )
select cte.id, cte.alternateid
from (select cte.*, max(lev) over (partition by id) as maxlev
      from cte
     ) cte
where lev = maxlev;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 2014-12-19
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多