mysql - mysql / sql:如何删除除每个用户的最后 N 个行之外的所有行?
问题描述
我有一个快速增长的消息(id、userid、message)表。
我想删除每个用户的所有消息,除了他的最后 30 条消息
例如:如果 user1 有 100 条消息,我们将删除前 70 条,
如果 user2 有 40 条消息,我们将删除前 10 条,
如果 userN 有 10 条消息,则不采取任何措施
有没有办法用一个 SQL 来做到这一点?
我现在的想法是用 PHP 和湖 N sql 做一个循环,这对 N 个用户来说很长。
解决方案
MySQL (pre 8.0) 没有真正方便的方法来做到这一点。一种方法使用变量来枚举值:
select m.*,
(@rn := if(@u = userid, @rn + 1,
if(@u := userid, 1, 1)
)
) as seqnum
from (select m.*
from messages m
order by userid, id desc
) m cross join
(select @u := -1, @rn := 0) params;
你可以把它变成一个delete
using join
:
delete m
from messages m join
(select m.*,
(@rn := if(@u = userid, @rn + 1,
if(@u := userid, 1, 1)
)
) as seqnum
from (select m.*
from messages m
order by userid, id desc
) m cross join
(select @u := -1, @rn := 0) params
) mm
on m.id = mm.id
where seqnum > 30;
正如我在评论中所说,我认为这不是解决现实问题的好方法。消息的历史很有用,可能还有其他方法可以实现您想要的性能。在经过调整的系统中,用户的 30 条消息和用户的 70 条消息之间的差异不应该对性能产生太大影响。
推荐阅读
- python - .wav、.aiff、.flac 文件的 Python 拖放
- python - 如何将列表的子数组连接到一个列表中;即创建一个平面列表?
- html - 将段落文本放置在视频背景上的 h1 下方
- github - 将 github 存储库迁移到新计算机?
- python - selenium,如何使用 send_keys() 在 whatsapp 中将表情符号发送给发件人?
- json - 如何维护一个主键 (col1) 和一个 json 数据类型列的多个分支
- scala - 如何关联 rlike 和 regex_extract
- r - 如何使用 R 找到 6 次多项式与已知斜率的切线相交的 x 值?
- python - 将 JSON 文件转换为平面表
- backup - Asus WebStorage 的备份服务对任何人都有效(或绝对无效)吗?