2013-06-11 5 views
0

У меня есть таблица mysql («c5_imgs») с столбцами «user_id» (varchar) и «date» (временная метка). Объем данных в этой таблице вырос намного больше, чем я ожидал, и теперь я пытаюсь удалить все записи для каждого user_id, кроме последних 5.mysql удаляет строки, сохраняя последние 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: запрос я закончил с использованием базировалась на ответ христианина:

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 

ответ

1

Вы можете сделать это в три этапа:

First

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

Обратите внимание, что вы могли бы упростить и повысить скорость первого шага, если у вас есть таблица пользователей, из которых вы можете получить различные идентификаторы пользователя.

Это не гарантирует сохранение пяти последних изображений. В случаях, когда дата является точной для более чем одного изображения в 5-й и последующих позициях, это не будет работать по мере необходимости.

+0

user_id, что бы не сработало, по крайней мере, не для всех пользователей user_id в то же время , Ваша первая таблица должна иметь все user_id и либо 5-й результат для каждого идентификатора пользователя, либо первый 5. – jvilhena

+0

Вы правы, извините, мой плохой для спешки – Christian

+0

Отредактировал мой ответ. Посмотрите, поможет ли это вам. – Christian

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

У меня этот запрос не запущен, но он должен работать. Если необходимо, приступайте к работе.

+0

спасибо, что решил часть моей проблемы :), но мне нужен более общий запрос, чтобы сделать то же самое для всех – jvilhena

Смежные вопросы