如何基于SQL表生成全量连续步骤组合链条?
生成SQL表中所有连续步骤链条的拆解记录
问题说明
给定包含SeqNo、StartStep、EndStep字段的临时表#forming,需找出所有连续的步骤链条,并将每条完整链条拆解为组成它的原始表行,最终按链条顺序排列输出。
示例1:无分支的线性链条
输入表 #forming
| SeqNo | StartStep | EndStep |
|---|---|---|
| 1 | A | B |
| 2 | B | C |
| 3 | C | D |
| 4 | X | Y |
预期完整链条
- A→B→C→D(由SeqNo 1、2、3组成)
- X→Y(由SeqNo 4组成)
输出表
| ChainID | SeqNo | StartStep | EndStep | ChainOrder |
|---|---|---|---|---|
| 1 | 1 | A | B | 1 |
| 1 | 2 | B | C | 2 |
| 1 | 3 | C | D | 3 |
| 2 | 4 | X | Y | 1 |
示例2:带分支的链条
输入表 #forming
| SeqNo | StartStep | EndStep |
|---|---|---|
| 1 | A | B |
| 2 | B | C |
| 3 | B | D |
| 4 | D | E |
预期完整链条
- A→B→C(由SeqNo 1、2组成)
- A→B→D→E(由SeqNo 1、3、4组成)
输出表
| ChainID | SeqNo | StartStep | EndStep | ChainOrder |
|---|---|---|---|---|
| 1 | 1 | A | B | 1 |
| 1 | 2 | B | C | 2 |
| 2 | 1 | A | B | 1 |
| 2 | 3 | B | D | 2 |
| 2 | 4 | D | E | 3 |
SQL实现方案
使用递归CTE(Common Table Expression)来追踪并拼接所有连续链条,代码如下:
WITH RecursiveChains AS ( -- 锚点:筛选所有链条的起始行(无前置步骤的记录) SELECT SeqNo, StartStep, EndStep, CAST(SeqNo AS VARCHAR(MAX)) AS PathSeq, 1 AS ChainOrder, DENSE_RANK() OVER(ORDER BY StartStep) AS ChainID FROM #forming f WHERE NOT EXISTS ( SELECT 1 FROM #forming f2 WHERE f2.EndStep = f.StartStep ) UNION ALL -- 递归:拼接后续步骤 SELECT f.SeqNo, rc.StartStep, f.EndStep, rc.PathSeq + ',' + CAST(f.SeqNo AS VARCHAR(MAX)), rc.ChainOrder + 1, rc.ChainID FROM RecursiveChains rc JOIN #forming f ON rc.EndStep = f.StartStep -- 防止循环步骤导致无限递归 WHERE CHARINDEX(',' + CAST(f.SeqNo AS VARCHAR(MAX)) + ',', ',' + rc.PathSeq + ',') = 0 ) -- 最终输出:按链条ID和步骤顺序排序 SELECT ChainID, SeqNo, StartStep, EndStep, ChainOrder FROM RecursiveChains ORDER BY ChainID, ChainOrder;
代码说明
- 锚点成员:筛选出所有没有前置步骤的记录(即
StartStep未出现在其他记录的EndStep中),作为每条链条的起点。 - 递归成员:通过
EndStep与StartStep的关联,逐步拼接后续步骤,同时记录当前链条的步骤顺序和SeqNo路径。 - 循环检测:使用
CHARINDEX判断当前步骤是否已存在于链条路径中,避免表中出现循环步骤时导致递归溢出。 - 排序:最终结果按
ChainID(链条唯一标识)和ChainOrder(步骤在链条中的位置)排序,确保链条顺序正确。
内容的提问来源于stack exchange,提问作者Sabreen Sageer
相关产品推荐
相关产品推荐

