删除除前n项之外的所有内容(Rails,PGSQL)

时间:2014-05-26 15:58:21

标签: ruby-on-rails-3 postgresql

假设我有一个名为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实现这一目标?

1 个答案:

答案 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之前备份数据。