在 SQL 服务器中为列中的每个更改(包括 NULL)保留一行

Keep a row for each change in column (including NULL) in SQL Server

我想跟踪 SQL 服务器中数据集的更改。

我目前有类似的数据

    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

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

使用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 值使这有点棘手。最后一个条件处理 ref 的第一行是 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;

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