【发布时间】:2018-09-19 01:16:18
【问题描述】:
假设我有一个历史表记录谁修改了数据
-------------------------------------------------------------
| ID | Last_Modif | User_Modif | Col3, Col4...
-------------------------------------------------------------
| 1 | 2018-04-09 12:12:00 | John
| 2 | 2018-04-09 11:10:00 | Jim
| 3 | 2018-04-09 11:05:00 | Mary
| 4 | 2018-04-09 11:00:00 | John
| 5 | 2018-04-09 10:56:00 | David
| 6 | 2018-04-09 10:53:00 | John
| 7 | 2018-04-08 19:50:00 | Eric
| 8 | 2018-04-08 18:50:00 | Chris
| 9 | 2018-04-08 15:50:00 | John
| 10 | 2018-04-08 12:50:00 | Chris
----------------------------------------------------------
我想找到 John 所做的修改以及他之前的版本,以检查他修改了什么。例如在这种情况下,我想返回第 1、2、4、5、6、7、9、10 行
我正在考虑首先根据 Last_modif 进行排名,然后进行连接以获取下一行,但不知何故结果不正确。这似乎不是 LAG/LEAD 案例,因为我不是从下一行中选择单个值,而是整个下一行。有什么想法吗?
-- sample 1000 rows with RowNumber
with TopRows as
(select top 1000 *, ROW_NUMBER() OVER(ORDER BY Last_modif desc) RowNum from [Table])
--Reference rows : Rows modif by John
, ModifByJohn as
(Select * from TopRows where USER_MODIF = 'John')
select * from ModifByJohn
UNION
select ModifByNext.* from ModifByJohn join TopRows ModifbyNext on ModifByJohn.RowNum + 1 = ModifByNext.RowNum
order by RowNum
如果我们想返回 John 之前的最后 2 个修改而不是 1,代码会是什么样子?
【问题讨论】:
-
这个概念是可以的,但是在验证窗口函数的时候不要做TOP N,因为结果是不确定的。为什么你得到错误的结果?请记住,如果 John 可能修改了多条记录,那么您的起点 (ModifByJohn) 将有几个分散的行号。几个修改日期的行号也可能存在关联(您应该解开其他列,以便每次都能获得一致的结果)。
-
ID设置的顺序和Last_Modif一样吗?
-
@Pettrucci :好点。如果约翰有一连串的修改,你会建议什么修改,以便我们只采用一个约翰。例如John1, John2, Mary 将返回 J, J, M 而不是 J1, J2, J2, Mary ? @ McNets:没有相关性,这就是为什么我 ORDER BY Last_Modif 并在那里放一个 ROW_NUMBER
标签: sql-server lag rank row-number lead