select 同一外键出现次数超过 X 次的行,忽略最近的 X 次(时间戳)

select the rows that have more that X occurrences of the same foreign key and ignore the X most recent (timestamp)

我有一个 table,其中一个 属性 是外键,另一个 属性 是时间戳

Table

id fk timestamp
1 2 16-02-2022
2 2 01-02-2022
3 2 02-02-2021
4 3 24-05-2020
5 3 11-01-2022
6 3 16-09-2021
7 3 01-01-2022

我想select相同外键出现X次以上的行,我想忽略每个外键的X个最近(时间戳)元素

所以基本上 X 为 2 时 select 会 return

id fk timestamp
3 2 02-02-2021
6 3 16-09-2021
4 3 24-05-2020

如果 X 为 3,select 将 return

id fk timestamp
4 3 24-05-2020

编辑:

非常感谢@forpas 的好方法

解决方案

SELECT id, fk, timestamp 
FROM (
  SELECT *,
         COUNT(*) OVER (PARTITION BY fk) counter,
         ROW_NUMBER() OVER (PARTITION BY fk ORDER BY timestamp DESC) rn
  FROM tablename
) t
WHERE counter > ? AND rn > ?;

使用COUNT()ROW_NUMBER()window函数:

SELECT id, fk, timestamp 
FROM (
  SELECT *,
         COUNT(*) OVER (PARTITION BY fk) counter,
         ROW_NUMBER() OVER (PARTITION BY fk ORDER BY timestamp DESC) rn
  FROM tablename
) t
WHERE counter > ? AND rn > ?;

? 替换为您想要的值。

但是,如果对每个 fk 的总行数和要取消的行数应用相同的数字 X,则可以简化查询:

SELECT id, fk, timestamp 
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY fk ORDER BY timestamp DESC) rn
  FROM tablename
) t
WHERE rn > ?;

参见demo

SELECT 
id, fk, timestamp
FROM
(
SELECT id, fk, timestamp, ROW_NUMBER() OVER(PARTITION BY fk ORDER BY timestamp ASC) AS X,
COUNT(1) OVER(PARTITION BY fk) AS Total
FROM MyTable
) AS S
WHERE A.Total - S.X >= @X