2015-12-28 70 views
2

我在尋找什麼類型的更新將在t-sql DML的特定場景中最好的一些建議。T-SQL將當前行更新到下一行的值問題

來到一個數據問題,即結束日期是在當前記錄的開始日期的前一天,並且需要將結束日期設定爲行的下一個的開始日期爲多個實體

例如

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 

我需要做的是將第一條記錄end_date更新爲每個員工/實體上的下一條記錄startdate - 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 

除了我長的臨時表的列表中的任何建議/更新將不勝感激!我正在考慮一些可能的遊標,但我不太確定這是否是寫這種場景更新的更快的方法。

+0

使用[SELF JOIN(http://www.tutorialspoint.com/sql/sql-self-joins.htm)用'LAG()'功能。 –

+0

提示:使用適當的軟件(MySQL,Oracle,DB2,...)和版本(例如, '的SQL服務器2014'。語法和功能的差異往往會影響答案。 – HABO

回答

2

我認爲可更新的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); 
+0

這很完美,謝謝。 – Jberrong

+0

這是一個很好和正確的答案。然而,一些&çà!è決定讓2008R2服務器在開發服務器爲2016年的時候進行升級和生活。任何人都可以請幫助我解決在2008R2上工作的解決方案 –