Fas*_*ous 0 t-sql sql-server sql-server-2008
我有一个包含重复事务记录的表。这些都是不错的重复项,但需要为它们分配值以使它们对于表来说是唯一的。记录的用途是按时间顺序查看它们,我使用 ROW_NUMBER 按 ID 和 ORDER BY 时间对它们进行分区。
有时它有效。有时会失败。
例子
CASE WHEN [Record] = 'Start'
THEN 0
ELSE -1 + ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [Date] DESC
END AS [RowNo]
Run Code Online (Sandbox Code Playgroud)
预期成绩
ID, Date, RowNo
2002, 12:30, 1
2002, 12:29, 2
2002, 12:29, 3
2002, 12:29, 4
2002, 12:28, 5
3212, 01:10, 1
3212, 01:09, 2
3212, 01:08, 3
Run Code Online (Sandbox Code Playgroud)
实际结果
ID, Date, RowNo
2002, 12:30, 1
2002, 12:29, 2 <---Right
2002, 12:29, 2 <---Wrong
2002, 12:29, 3 <---Right
2002, 12:28, 4
3212, 01:10, 1
3212, 01:09, 2
3212, 01:08, 3
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来保证准确性?
嗯。 ROW_NUMBER()
确实适用于重复记录。(当存在重复项时,无法确定哪一行将获得哪个值。)
你的陈述中还存在其他一些未显示的内容。一个连接操作,一个 GROUP BY,一些额外的过滤。我们不知道那是什么,但我们知道这ROW_NUMBER()
确实适用于重复项。
编辑
这很可疑:
CASE WHEN [Record] = 'Start'
THEN 0
ELSE -1 + ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [Date] DESC
END AS [RowNo]
Run Code Online (Sandbox Code Playgroud)
CASE
我以前从未在表达式中见过这样的分析函数。在我看来,ROW_NUMBER()
只有在ELSE
. (我不确定 SQL Server 实际上是如何处理的。)
如果我想RowNo
成为 0, 1, 2, ... 我只需减去 1...
ROW_NUMBER() OVER(PARTITION BY [ID] ORDER BY [Date] DESC) - 1 AS RowNo
Run Code Online (Sandbox Code Playgroud)
如果需要将条件纳入[Record] = 'Start'
作为评估的一部分ROW_NUMBER
,那么我会将其包含在PARTITION
OVER(PARTITION BY [ID],CASE WHEN [Record]='Start' THEN 0 END ORDER BY ...)
Run Code Online (Sandbox Code Playgroud)
如果我需要操作 ROW_NUMBER() 返回的值,我会找到一种方法在内联视图或 CTE 的上下文中对其进行评估,以对其进行评估并返回,然后对返回的值进行处理外部查询中的值。
重点是它ROW_NUMBER()
可以很好地处理重复项。如果您得到的结果不是您所期望的,那是因为语句中还存在其他内容,例如 CASE 表达式、联接或其他内容。