存储和查询实体沿袭

时间:2017-05-11 18:51:11

标签: sql sql-server database data-structures

假设有一个合约数据表,恰当地命名为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
----------

我不是在寻找完整的代码解决方案,而是在设计中朝着正确的方向前进。这感觉就像一个递归的自我加入",如果有这样的事情,我就迷失了。

1 个答案:

答案 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