如何获得在分区更改时重新启动的 RANK? 我有这张表:
ID Date Value
1 2015-01-01 1
2 2015-01-02 1 <redundant
3 2015-01-03 2
4 2015-01-05 2 <redundant
5 2015-01-06 1
6 2015-01-08 1 <redundant
7 2015-01-09 1 <redundant
8 2015-01-10 2
9 2015-01-11 3
10 2015-01-12 3 <redundant
并且我正在尝试删除上一个条目中值未更改的所有行(标记为<冗余)。 我尝试过使用游标,但它花费的时间太长,因为该表大约有 5000 万行。
我也尝试过使用 RANK:
SELECT ID, Date, Value,
RANK() over(partition by Value order by Date ASC) Rank,
FROM DataLogging
ORDER BY Date ASC
但我得到:
ID Date Value Rank (Rank)
1 2015-01-01 1 1 (1)
2 2015-01-02 1 2 (2)
3 2015-01-03 2 1 (1)
4 2015-01-05 2 2 (2)
5 2015-01-06 1 3 (1)
6 2015-01-08 1 4 (2)
7 2015-01-09 1 5 (3)
8 2015-01-10 2 3 (1)
9 2015-01-11 3 1 (1)
10 2015-01-12 3 2 (2)
括号中的 是我想要的 Rank,这样我就可以过滤掉 Rank = 1 的行并删除其余的行。
编辑:我已经接受了似乎最容易编写的答案,但不幸的是,没有一个答案运行得足够快来删除行。 最后我决定使用CURSOR。我将数据分成大约 250k 行的 block ,游标运行并删除每批 250k 行约 11 分钟的行,下面的答案,使用 DELETE,每批 250k 行约花费 35 分钟。
最佳答案
这是一种有点复杂的方法:
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(ORDER BY [Date]) RN1,
ROW_NUMBER() OVER(PARTITION BY Value ORDER BY [Date]) RN2
FROM dbo.YourTable
), CTE2 AS
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY Value, RN1 - RN2 ORDER BY [Date]) N
FROM CTE
)
SELECT *
FROM CTE2
ORDER BY ID;
结果是:
╔════╦════════════╦═══════╦═════╦═════╦═══╗
║ ID ║ Date ║ Value ║ RN1 ║ RN2 ║ N ║
╠════╬════════════╬═══════╬═════╬═════╬═══╣
║ 1 ║ 2015-01-01 ║ 1 ║ 1 ║ 1 ║ 1 ║
║ 2 ║ 2015-01-02 ║ 1 ║ 2 ║ 2 ║ 2 ║
║ 3 ║ 2015-01-03 ║ 2 ║ 3 ║ 1 ║ 1 ║
║ 4 ║ 2015-01-05 ║ 2 ║ 4 ║ 2 ║ 2 ║
║ 5 ║ 2015-01-06 ║ 1 ║ 5 ║ 3 ║ 1 ║
║ 6 ║ 2015-01-08 ║ 1 ║ 6 ║ 4 ║ 2 ║
║ 7 ║ 2015-01-09 ║ 1 ║ 7 ║ 5 ║ 3 ║
║ 8 ║ 2015-01-10 ║ 2 ║ 8 ║ 3 ║ 1 ║
║ 9 ║ 2015-01-11 ║ 3 ║ 9 ║ 1 ║ 1 ║
║ 10 ║ 2015-01-12 ║ 3 ║ 10 ║ 2 ║ 2 ║
╚════╩════════════╩═══════╩═════╩═════╩═══╝
要删除您不需要的行,您只需执行以下操作:
DELETE FROM CTE2
WHERE N > 1;
关于sql - RANK() OVER PARTITION 并重置 RANK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35208241/