1

i have a MySQL table having columns as below

chat_id     sender  receiver    msg     msg_time

i need a query that will execute every day to delete all messages except latest 20 messages received by each receiver.is there a single query or i need to do some code in PhP or any other programming language

4

4 回答 4

3

Try this query

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;

This select query will return all the records other than last 20 for each user, you can use it accordingly in your delete statement..

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
于 2013-05-31T12:47:57.853 回答
2

You can actually do it using correlated subquery and without using any user variables.

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

the current query will remove all the records except for the 3 latest record for each receiver based on msg_time. Just change 3 to 20 to fit your needs.

于 2013-05-31T12:49:11.827 回答
0

If you can run this query each day (maybe with a cronjob), it should be ok. I'm not entirely sure about the query, but it sure is a start.

DELETE FROM messages 
WHERE chat_id NOT IN (
    SELECT chat_id 
    FROM messages 
    GROUP BY sender 
    ORDER BY msg_time DESC 
    LIMIT 20
)
于 2013-05-31T12:46:53.807 回答
-1

If you have an auto-incrementing index, you could do it in one query. Just delete everything with index < max_index - 20 ...

You will need a subquery and the max function to do it

于 2013-05-31T12:43:21.300 回答