对于SQL Server中的列(包括NULL)的每个更改都保留一行

问题描述 投票:1回答:1

我想跟踪对SQL Server中数据集的更改。

我目前有与此类似的数据

    Unique Ref  FromDate    ToDate     Status
           1    01/01/2020  03/01/2020  A
           1    03/01/2020  03/02/2020  NULL
           1    03/02/2020  04/04/2020  B
           1    04/04/2020  05/04/2020  B
           1    05/04/2020  06/06/2020  A
           2    03/01/2020  05/01/2020  NULL
           2    05/01/2020  06/07/2020  B
           2    06/07/2020  07/07/2020  B
           2    07/07/2020  08/07/2020  A

我想针对由唯一引用分组的状态的每次更改都保留一行,这样我只能看到更改,而不能看到状态保持不变。

试图使上面看起来像

Unique Ref  Status  ChangedDate
         1  A       01/01/2020
         1  NULL    03/01/2020
         1  B       03/02/2020
         1  A       05/04/2020
         2  NULL    03/01/2020
         2  B       05/01/2020
         2  A       07/07/2020

我之前从未做过类似的事情,所以不确定从哪里开始。

sql sql-server tracking
1个回答
1
投票

使用lag()。我认为这可以满足您的要求:

select t.ref, t.status, t.fromDate as changedDate
from (select t.*,
             lag(status) over (partition by ref order by fromDate) as prev_status,
             row_number() over (partition by ref order fromDate) as seqnum
      from t
     ) t
where prev_status <> status or
      prev_status is null and status is not null or
      prev_status is not null and status is null or
      seqnum = 1;

NULL值使此操作有些棘手。当引用的第一行是NULL时,最后一个条件将处理这种情况。

另一种方法我认为更简单:

select t.ref, t.status, t.fromDate as changedDate
from (select t.*,
             lag(fromDate) over (partition by ref order by fromDate) as prev_date,
             lag(fromDate) over (partition by ref, status order by fromDate) as prev_status_date
      from t
     ) t
where prev_status_date is null or
      prev_status_date <> prev_date;

这只是将状态的先前日期与整个记录的先前日期进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.