假设有一个合约数据表,恰当地命名为dbo.Contracts。合同到期后,将在表格中创建一个新行。我需要用新合同跟踪旧合同的合同号。例如,合同号123456今天到期。该申请今天创建续约合同(合同号888888)。属于合同号888888的行的字段dbo.Contract.PreviousContractID更新为123456。
一切都很顺利。然而,最终这些年来将会有一个"链"合同123456续签合同888888,更新为999999等等。
----------------------------------------------------------------
Table dbo.Contracts
----------------------------------------------------------------
ContractID | Lots of other fields | PreviousContractID
----------------------------------------------------------------
123456 | | NULL
----------------------------------------------------------------
888888 | | 123456
----------------------------------------------------------------
999999 | | 888888
我如何编写一个查询来说明"给定合同号999999,查询链中的所有合同。"我不知道从哪里开始。我甚至不确定添加字段dbo.Contracts.PreviousContractID甚至是正确的设计。
所需的查询会说,"对于合同号999999,获取''"中的所有合同:
@ContractID = 999999
Result set:
----------
ContractID
----------
999999
----------
888888
----------
123456
----------
我不是在寻找完整的代码解决方案,而是在设计中朝着正确的方向前进。这感觉就像一个递归的自我加入",如果有这样的事情,我就迷失了。
答案 0 :(得分:1)
一个简单的重复CTE应该可以做到这一点
Declare @YourTable Table ([ContractID] varchar(50),[PreviousContractID] varchar(50))
Insert Into @YourTable Values
(123456,NULL)
,(888888,123456)
,(999999,888888)
Declare @ContractID int = 999999
;with cteHB as (
Select [ContractID]
,[PreviousContractID]
,Lvl=1
From @YourTable
Where [ContractID]=@ContractID
Union All
Select R.[ContractID]
,R.[PreviousContractID]
,P.Lvl+1
From @YourTable R
Join cteHB P on P.[PreviousContractID] = R.[ContractID])
Select Lvl
,A.[ContractID]
,A.[PreviousContractID]
From cteHB A
Order By 1
返回
Lvl ContractID PreviousContractID
1 999999 888888
2 888888 123456
3 123456 NULL