我正在构建一个活动流,因此旧消息会从最终消失,永远不会再被看到。所以,我想定期删除旧邮件。但是,我不希望它看起来像用户没有活动,所以我想在每个流中留下至少X个帖子。
简化,我的“消息”表有一个“mid”(消息ID,主键),一个“uid”(用户ID),一个“创建”日期(UNIX时间戳)和一个“消息”。所以我想做的是做这样的事情:
DELETE FROM messages
WHERE created < ? AND mid NOT IN (
SELECT mid FROM messages m GROUP BY uid HAVING mid > (
SELECT mid FROM messages WHERE uid = m.uid ORDER BY mid LIMIT 1 OFFSET ?
)
)
但是,当我单独在NOT IN()
内尝试查询时,它不返回任何结果。此外,我认为它不适用于您要删除的同一个表中的SELECT
。
如果有必要,我可以使用2个查询,但我希望没有必要。
我试过四处搜索,除了最后一条记录之外,还有很多关于如何删除所有内容的结果,但我没有找到任何关于删除除最后N条记录以外的内容的结果。
答案 0 :(得分:2)
请查看这个问题,找出“每组前n个”问题的[mysql]解决方案:
How to SELECT the newest four items per category?
一旦你有一组由“每组前n个”中的所有行组成(这就是你想要保留的)。您只需删除那些不在该集合中的行:
delete x
where x.mid not in ( select mid
-- where top n per group criteria
)
这是另一个查看同一问题的链接:
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
答案 1 :(得分:1)
这模拟了sql server窗口函数行号,它按日期对每条消息进行编号。然后只删除数字大于10的消息。您可能需要在l.created&gt; = r.created之间翻转相等。
delete from messages
where mid in
(select l.mid from (
select l.mid,l.created, count(*) as num
from messages as l
left outer join messages as r
on l.mid = r.mid
and l.created >= r.created
group by l.mid, l.created) a
where a.num > 10
and l.created < ?);