在sql server的列(包括null)中为每个更改保留一行

oxalkeyp  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(289)

我想跟踪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分组,这样我只能看到更改,而不能看到状态保持不变的地方。
试图让上面看起来像

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

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

rryofs0p

rryofs0p1#

使用 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;

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

相关问题