我有一个mysql表(“c5_imgs”),其中包含“user_id”(varchar)和“date”(时间戳)列。此特定表中的数据量增长远远超过我最初的预期,现在我正在尝试删除除最近5个之外的每个user_id的所有记录。
对于给定的user_id,我可以获取要删除的行:
select *
FROM c5_imgs i
where
date < (
select date
from c5_imgs i2
where i.user_id = i2.user_id
order by i2.date desc
limit 4,1
)
and user_id = 'xxx'
但是我在删除这些行时遇到了问题:
delete
FROM c5_imgs
where
date < (
select date
from c5_imgs i2
where 'xxx' = i2.user_id
order by i2.date desc
limit 4,1
)
and user_id = 'xxx'
#1093 - You can't specify target table 'c5_imgs' for update in FROM clause
我希望为所有user_id制作一个通用查询,而不是一次一个...任何帮助将不胜感激,谢谢。
编辑:chetan的回答帮助我删除了一个user_id,但我正在为所有user_id寻找更通用的解决方案。
Edit2 :我最终使用的查询基于Christian的回答:
delete aa.*
from c5_imgs aa,
(
select distinct c.user_id as user_id,
(select x.date
from c5_imgs as x
where x.user_id = c.user_id
order by x.date desc
limit 4,1) as date
from c5_imgs as c
) bb
where aa.user_id = bb.user_id and aa.date < bb.date
答案 0 :(得分:1)
你可以使用join来做到这一点。例如
delete a.*
FROM c5_imgs a, (
select date
from c5_imgs
where 'xxx' = user_id
order by date desc
limit 4,1
) b
where
a.date < b.date
and a.user_id = 'xxx';
我没有运行此查询,但它应该可以运行。必要时可以解决。
答案 1 :(得分:1)
您可以分三步完成:
create table aux
select distinct c.user_id as user_id,
(select x.date
from c5_imgs as x
where x.user_id = c.user_id
order by x.date desc
limit 4,1) as date
from c5_imgs as c;
第二
delete c5_imgs
from c5_imgs as c
inner join aux as a on a.user_id = c.user_id
where c.date < a.date;
第三
drop table aux;
如果使用大表,可以在aux表的列上创建索引以加快删除操作。
CREATE INDEX aux_idx1 ON aux(user_id);
CREATE INDEX aux_idx2 ON aux(date);
请注意,如果您有一个可以获取不同用户ID的用户表,则可以简化并提高第一步的速度。
这并不能保证准确保留5张最近的图片。如果第5个和下一个位置的多个图像的日期完全相同,则无法按要求运行。