【问题标题】:How to use Recursive CTE on Effective Dates如何在生效日期上使用递归 CTE
【发布时间】:2015-06-24 21:23:42
【问题描述】:

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

示例文件

最终结果

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

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

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

【问题讨论】:

  • 我什至无法推断您将如何从第一个状态进入第二个状态。 “2050-01-01”从何而来?
  • 最新的EntityEffectiveDate可以有一个EffectiveToDate,比如说EntityEffectiveDate + 20年,但是之前的EntityEffectiveDate必须是之前的生效日期——1天。我可以通过一个游标完成所有这些操作,这需要大约 12 秒来运行所有内容。但我知道必须有一种方法可以使用 Recursive CTE 来做到这一点,而且速度要快得多。我也很近。

标签: date recursion common-table-expression


【解决方案1】:

这个反应不是关于 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),如果有的话(左连接)。

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

【讨论】:

  • 谢谢马丁。绝对是我正在寻找的结果。你帮我把这个查询的时间至少分成了一半。非常感谢!
猜你喜欢
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2021-10-19
相关资源
最近更新 更多