如何在生效日期使用递归 CTE

How to use Recursive CTE on Effective Dates

下面的安装文件包含回答问题所需的所有数据。

示例文件

最终结果

问题:如您在示例文件屏幕截图中所见,我继承了一个数据库,该数据库存储实体开始与特定 EntityLocation 关联的有效日期。在示例图像中,实体 10170 与 EntityLocation 的最近关联是 2011-01-01,之前是 2006-01-01,依此类推...(参见示例文件屏幕截图)

问题:在样本数据上使用递归 CTE 我希望 return 结果看起来像最终结果样本,我如何使用递归 CTE 而不是游标来完成此操作。 (参见最终结果示例)

设置文件:sample xlsx,其中包含完整数据。

这个反应不是关于 CTE,而是关于让你找到这个特定问题的解决方案。这里不需要递归。只有当您必须多次迭代 link 自身时才需要递归。如果您想学习 CTE,请尝试制作例如一个器官图。

您的解决方案是 link 将 EffectiveDate 作为 Opendate 转换为另一个 EffectiveDate 作为 Closedate(如果有的话)。

首先,您可能希望使用带分区的 ROW_NUMBER() 函数为每个实体创建一个位置索引。所以我的新 table location 将被定义为

SELECT ROW_NUMBER() OVER (partition BY EntityId ORDER BY EntityEffectiveDate ASC) as LocId, 
    EntityId, EntityLocation, EntityEffectiveDate 
INTO Location 
FROM YourOldEntityLocation

现在您可以link 将每个位置(等于 entityId)的生效日期更改为该位置的下一个生效日期 (LocId+1)(如果有一个(LEFT JOIN))。

SELECT opendate.LocId, opendate.EntityId, opendate.EntityLocation, opendate.EntityEffectiveDate,
   isnull(closedate.EntityEffectiveDate,'2050-01-01') as EffectiveToDate
FROM Location as opendate 
   LEFT JOIN Location as closedate 
      ON closedate.entityId = opendate.entityId 
      AND opendate.LocId+1 = closedate.LocId
ORDER BY opendate.EntityId, EntityEffectiveDate DESC

这导致:

LocId   EntityId    EntityLocation  EntityEffectiveDate EffectiveToDate
3   10170   63  2011-01-01  2050-01-01
2   10170   31  2006-01-01  2011-01-01
1   10170   43  2003-07-01  2006-01-01
3   11674   45  2014-07-01  2050-01-01
2   11674   29  2004-10-01  2014-07-01
1   11674   45  2003-04-01  2004-10-01
3   11675   45  2011-04-01  2050-01-01
2   11675   29  2004-10-01  2011-04-01
1   11675   45  2003-04-01  2004-10-01

根据您的要求。

建议完全不要替换 NULL 值。根据@Jack 的反应,您不必幻想未来的约会。结果很简单,告诉您此 EntityLocation 没有关闭日期。

通过select在此列中输入 NULL 值,select 实际位置很简单。结果将是:

LocId   EntityId    EntityLocation  EntityEffectiveDate EffectiveToDate
3   10170   63  2011-01-01  NULL
2   10170   31  2006-01-01  2011-01-01
1   10170   43  2003-07-01  2006-01-01
3   11674   45  2014-07-01  NULL
2   11674   29  2004-10-01  2014-07-01
1   11674   45  2003-04-01  2004-10-01
3   11675   45  2011-04-01  NULL
2   11675   29  2004-10-01  2011-04-01
1   11675   45  2003-04-01  2004-10-01