我有一个MySQL表,其中的列如下
chat_id sender receiver msg msg_time
我需要一个每天都会执行的查询来删除除了每个接收者收到的最新20条消息之外的所有消息。有一个查询或我需要用PhP或任何其他编程语言做一些代码
答案 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 ...
你需要一个子查询和最大函数来完成它