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

时间:2015-06-24 21:23:42

标签: date recursion common-table-expression

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

示例文件

sample file screenshot

最终结果

end result sample

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

问题:对样本数据使用递归CTE我希望返回结果看起来像最终结果样本,我如何使用递归CTE和NOT游标完成此操作。 (参见最终结果样本)

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

1 个答案:

答案 0 :(得分:0)

这个反应不是关于CTE,而是关于让你找到这个特定问题的解决方案。你这里不需要递归。只有在必须多次迭代链接到自身时,才需要递归。如果你想研究CTE,试着去做例如一个器官图。

您的解决方案是将EffectiveDate作为Opendate链接到另一个EffectiveDate作为Closedate,如果有的话。

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

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

现在,您可以将每个位置的有效日期(相等的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没有关闭。

通过在此列中选择NULL值来选择实际位置非常简单。结果将是:

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