Postgresql 通过超过限制的复合键删除记录

Postgresql 通过超过限制的复合键删除记录,postgresql,Postgresql,考虑这样的表模式 id | user | target | timestamp 这个表会不断填充,但我只想保留来自任何用户/目标组合的最后10条记录。我可以在插入时修改它,或者作为一项任务一次清除所有记录,或者介于两者之间,但是我不知道如何做。我知道我可以做像这样的事情 从表名中删除 我不在哪里 从tableName中选择id 其中用户=1,目标=1 限制10 按时间戳顺序描述 但这样做,我只能做一个用户/目标组合在一次。有没有一种方法可以构造我的查询,以删除包含10条以上记录的所有组合,或者

考虑这样的表模式

id | user | target | timestamp
这个表会不断填充,但我只想保留来自任何用户/目标组合的最后10条记录。我可以在插入时修改它,或者作为一项任务一次清除所有记录,或者介于两者之间,但是我不知道如何做。我知道我可以做像这样的事情

从表名中删除 我不在哪里 从tableName中选择id 其中用户=1,目标=1 限制10 按时间戳顺序描述 但这样做,我只能做一个用户/目标组合在一次。有没有一种方法可以构造我的查询,以删除包含10条以上记录的所有组合,或者在插入时有没有一种方法可以在插入时删除最新的记录

基本上,我只想记录最后10个条目。在闲逛了一段时间后,我认为这很接近:

…我在哪里 从中选择id 选择 身份证件 按用户进行的行数超额分配,按时间戳描述的目标订单为行 从桌子上 行>10的行 这似乎让我看到每组的行数超过10行。它似乎在做我认为应该做的事情吗?

应该做:

DELETE FROM tablename
USING (SELECT id
       FROM tablename 
       WHERE "user" = 1 and target = 1 
       ORDER BY timestamp DESC
       OFFSET 10) AS ids
WHERE tablename.id = ids.id;
这是使用偏移的地方之一

对于速度,在用户、目标上建立索引,其中顺序无关紧要


避免命名表或列用户,因为它是SQL关键字。

您的尝试非常接近

以下内容将删除每个用户、目标组合(按时间戳排序)最近10个记录之前的所有记录

但是请注意,row_number将为等效行分配一个不同的值,即共享相同时间戳的两行。在多行具有相同年龄的场景中,将保留第十行中的一行,如果有其他行,则将删除它们,并且在查询中不定义选择哪一行。rank为相等的行指定相同的值,因此,如果有多行与第十行的年龄相同,rank将保留所有行。需要考虑的事项,因为您将删除可能无法恢复

的数据。
delete from tablename
using (select
         id
       , row_number() over (partition by user, target order by timestamp desc) rn
       from tablename) as ranked
where tablename.id = ranked.id 
  and ranked.rn > 10