在 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;
这只是将状态的前一个日期与整个记录的前一个日期进行比较。
我想跟踪 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;
这只是将状态的前一个日期与整个记录的前一个日期进行比较。