Sql-Server

如何合併具有不同有效期的相似記錄?

  • February 16, 2018

我正在處理的表包含三個組件:

  1. ID列(另一個表中的主鍵)
  2. 一些數據列
  3. 有效日期from/to列。

價值觀:

ID   Data From        To  
1    a    2015-01-01  2015-01-05
1    a    2015-01-06  2015-01-10
1    b    2015-01-11  2015-01-15
1    a    2015-01-16  2015-01-20
2    c    2015-01-01  2015-01-05
2    c    2015-01-06  2015-01-10

該表是通過每隔一段時間獲取另一個數據源的“快照”並將有效日期分配給記錄來更新的。問題是這些快照會為在該時間間隔內根本沒有更改的記錄(具有不同的有效日期)創建重複條目。

我想通過查找具有連續日期的行並合併它們並為其分配一個有效期來減小表的大小。例如:

ID   Data From        To  
1    a    2015-01-01  2015-01-10
1    b    2015-01-11  2015-01-15
1    a    2015-01-16  2015-01-20
2    c    2015-01-01  2015-01-10

我目前的邏輯是:

  1. 按 ID、數據欄位和“有效自”欄位選擇和排序所有行(因此它們位於連續行的組中)。
  2. 使用游標比較相鄰行的相似性。
  3. 如果它們相同,則合併行並更改有效期以包括這兩行。

我知道游標效率很低(我有一個大數據集),所以我正在尋找其他方法。

如果這只是一個背靠背範圍表,您的案例可以被視為經典的“間隙和孤島”問題,您只需隔離連續範圍的孤島,然後通過取最小值[from][to]每個島嶼的最大值。

有一種使用兩個 ROW_NUMBER 呼叫解決此問題的既定方法:

WITH islands AS
(
 SELECT
   id,
   data,
   [from],
   [to],
   island = ROW_NUMBER() OVER (PARTITION BY id       ORDER BY [from])
          - ROW_NUMBER() OVER (PARTITION BY id, data ORDER BY [from])
 FROM
   #mergeTest
)
SELECT
 id,
 data,
 [from] = MIN([from]),
 [to]   = MAX([to])
FROM
 islands
GROUP BY
 id,
 data,
 island
;

此查詢將在與 SQL Server 2005 一樣低的版本中工作。

引用自:https://dba.stackexchange.com/questions/107508