Sql 存储和查询实体沿袭
假设有一个合同数据表,恰当地命名为dbo.Contracts。合同到期后,将在表中创建新行。我需要跟踪旧合同和新合同的合同号。例如,合同号123456今天到期。应用程序今天创建续订合同(合同号888888)。属于合同编号8888的行的字段dbo.Contracts.PreviousContractID更新为123456 没关系。然而,多年以后,最终会有一系列合同。123456续签为合同888888,合同续签为999999等Sql 存储和查询实体沿袭,sql,sql-server,database,data-structures,Sql,Sql Server,Database,Data Structures,假设有一个合同数据表,恰当地命名为dbo.Contracts。合同到期后,将在表中创建新行。我需要跟踪旧合同和新合同的合同号。例如,合同号123456今天到期。应用程序今天创建续订合同(合同号888888)。属于合同编号8888的行的字段dbo.Contracts.PreviousContractID更新为123456 没关系。然而,多年以后,最终会有一系列合同。123456续签为合同888888,合同续签为999999等 ------------------------------------
----------------------------------------------------------------
Table dbo.Contracts
----------------------------------------------------------------
ContractID | Lots of other fields | PreviousContractID
----------------------------------------------------------------
123456 | | NULL
----------------------------------------------------------------
888888 | | 123456
----------------------------------------------------------------
999999 | | 888888
我如何写一个查询,说“给定合同号9999999,查询链中的所有合同。”我不知道从哪里开始。我甚至不确定添加一个字段dbo.Contracts.PreviousContractID是否是正确的设计
所需的查询将显示“对于合同号999999,获取“链”中的所有合同”:
我不是在寻找一个完整的代码解决方案,而是在设计中朝着正确的方向前进。这感觉就像是一个“递归自连接”,如果有这样的事情,我会迷路的。一个简单的递归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
你应该研究一下。那么,这怎么不是一个复制品呢?…甚至是正确的设计。我也不是。正确的设计取决于你的目标和你试图建立的模型。也许您需要在“扩展”之间形成某种父级关系,这意味着至少有一个其他表和透视图的更改。有时候,你需要尝试不同的方法来处理你的表格,并根据你的数据/目标来验证它们。@ZoharPeled我真诚地没有不尊重的意思。我甚至不知道我重新开放的投票会推翻你的投票。也就是说,你链接到了自上而下,而OP需要自下而上。没问题,我只是想知道。嗯,几乎所有的递归cte问题都是重复的,所以我很惊讶,仅此而已。这应该可以做到。谢谢@硬编码很高兴它有帮助。
Lvl ContractID PreviousContractID
1 999999 888888
2 888888 123456
3 123456 NULL