MySQL删除除了每个人的最后20个以外的所有条目

时间:2013-05-31 12:40:03

标签: mysql sql

我有一个MySQL表,其中的列如下

chat_id     sender  receiver    msg     msg_time

我需要一个每天都会执行的查询来删除除了每个接收者收到的最新20条消息之外的所有消息。有一个查询或我需要用PhP或任何其他编程语言做一些代码

4 个答案:

答案 0 :(得分:3)

尝试此查询

select 
    *
from
(select 
    @rn:=if(@prv=receiver, @rn+1, 1) as rId,
    @prv:=receiver as receiver,
    chat_id,
    sender,
    msg,
    msg_time
from  
    tbl
join
    (select @rn:=0, @prv:='')tmp
order by 
    receiver, msg_time desc)tmp
where rid >= 20;

此选择查询将返回每个用户的最后20个以外的所有记录,您可以在删除语句中相应地使用它。

delete 
   a
from 
   tbl a
inner join 
   (select 
       @rn:=if(@prv=receiver, @rn+1, 1) as rId,
       @prv:=receiver as receiver,
       chat_id,
       sender,
       msg,
       msg_time
   from  
       tbl
   join
       (select @rn:=0, @prv:='')tmp
   order by 
       receiver, msg_time desc
   )tmp
 on 
   a.chat_id=tmp.chat_id
 where 
   tmp.rId >20

答案 1 :(得分:2)

您实际上可以使用相关子查询并且不使用任何用户变量来执行此操作。

DELETE  a
FROM    TableName a
        LEFT JOIN
        (
            SELECT  *, 
                    (
                        SELECT  COUNT(*)
                        FROM    tableName c
                        WHERE   c.receiver = a.receiver AND
                                c.msg_time >= a.msg_time) AS RowNumber
            FROM    TableName a
        ) b ON a.receiver = b.receiver AND
                a.msg_time = b.msg_time AND
                b.RowNumber <= 3 -- <<== change this to your desired value
WHERE   b.receiver IS NULL

当前查询将删除除基于receiver的每个msg_time的3条最新记录以外的所有记录。只需将3更改为20即可满足您的需求。

答案 2 :(得分:0)

如果您每天都可以运行此查询(可能使用cronjob),那么它应该没问题。 我不完全确定查询,但肯定是一个开始。

DELETE FROM messages 
WHERE chat_id NOT IN (
    SELECT chat_id 
    FROM messages 
    GROUP BY sender 
    ORDER BY msg_time DESC 
    LIMIT 20
)

答案 3 :(得分:-1)

如果您有自动递增索引,则可以在一个查询中执行此操作。只需删除索引&lt;的所有内容max_index - 20 ...

你需要一个子查询和最大函数来完成它