一尘不染

T-SQL将当前行更新为下一行的值问题

sql

我正在寻找有关在某种情况下对于t-sql DML最好的更新类型的一些建议。

发生数据问题,其结束日期是当前记录的开始日期之前的一天,并且需要将结束日期设置为多个实体的下一行的开始日期

例如

rowid     entity    id  record_type start_date  end_date
214       250       1   H           2015-01-01  2014-12-31
329       250       1   H           2015-04-25  2015-04-24
533       250       1   C           2015-11-01  NULL
11        250       2   H           2015-06-01  2014-05-29
292       250       2   H           2015-09-11  2015-09-10
987       250       2   C           2015-10-01  NULL

我需要做的是将第一个记录的结束日期更新为下一个记录的开始日期-每个员工/实体上为1。

当前,有超过5K个实体受此影响,所以我试图以某种方式在每条记录上更新此记录,以节省此时间。

我所能做的,但是要花很多时间,是:1.将所有公司的历史记录的最大行数汇总为一个数字; 2.为总行数创建相同数量的临时表;
3.插入最小开始日期值放入第一个临时表4.将不在临时表1中的最小值插入表2中,依此类推5.然后将临时表1的结束日期更新为临时表2的开始日期-1第6天。从此处开始,对实际表进行更新每个临时表具有多个更新语句,并在rowid上联接。

最终输出如下所示:

rowid     entity    id  record_type start_date  end_date
214       250       1   H           2015-01-01  2014-04-24
329       250       1   H           2015-04-25  2015-10-31
533       250       1   C           2015-11-01  NULL
11        250       2   H           2015-06-01  2014-09-10
292       250       2   H           2015-09-11  2015-9-31
987       250       2   C           2015-10-01  NULL

除了我的一堆临时表/更新之外的任何建议,我们将不胜感激!我在想一些可能的游标的方法,但是我不太确定这是否是为这种情况编写更新的更快方法。


阅读 133

收藏
2021-05-23

共1个答案

一尘不染

我认为可更新的CTE是必经之路。在SQL Server 2012+中,可以使用lead()

with toupdate as (
      select t.*,
             lead(start_date) over (partition by entity order by start_date) as next_start_date
      from t
     )
update toupdate
     set end_date = dateadd(day, -1, next_start_date)
     where end_date = dateadd(day, -1, start_date);
2021-05-23