假设我有一个名为post的表,属于用户。
class Post < ActiveRecord::Base
belongs_to :user
end
class User < activeRecord::Base
has_many :posts
end
这样posts
表包含user_id
列。
我如何定期删除每个用户的posts
表中除前n个帖子之外的所有帖子?
假设n = 20
如果用户有15个帖子,则会保留所有15个帖子。
如果用户有21个帖子,则会删除1个帖子。 1是最老的。
基本上我需要做一个FIFO但是要分组到user_id
列。
如何通过原始PostgreSQL sql实现这一目标?
答案 0 :(得分:1)
您可以在公用表表达式中使用ROW_NUMBER()
对帖子进行排名,将每个user_id的最新值排名为1(对于较旧的帖子,将其增加)。然后只需使用简单删除即可删除排名大于20的所有行;
WITH cte AS (
SELECT id, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY id DESC) rn
FROM post
)
DELETE FROM post
WHERE id IN (SELECT id FROM cte WHERE rn>20);
A simple SQLfiddle to test with
与往常一样,在从Internet上的随机用户运行可能具有破坏性的SQL之前备份数据。