0

我有一个 mysql 表(“c5_imgs”),其中包含“user_id”(varchar)和“date”(时间戳)列。这个特定表中的数据量增长得比我最初预期的要多得多,现在我试图删除每个 user_id 的所有记录,除了最近的 5 条记录。

对于给定的 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
4

2 回答 2

1

您可以使用加入来做到这一点。例如

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';

我没有运行这个查询,但它应该可以工作。如有必要,请解决。

于 2013-06-11T02:03:56.583 回答
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;

如果使用大型表,您可以在辅助表的列上创建索引以加快删除操作。

CREATE INDEX aux_idx1 ON aux(user_id);
CREATE INDEX aux_idx2 ON aux(date);

请注意,如果您有一个可以从中获取不同用户 ID 的用户表,则可以简化和提高第一步的速度。

这并不能保证准确保留 5 张最近的图像。如果第 5 和下一个位置的多个图像的日期完全相同,这将无法按要求工作。

于 2013-06-11T02:09:02.537 回答