2016-10-04 13 views
1

Оператор удаления MySQL на основе подвыборки с несколькими возвращаемыми значениями.Оператор удаления MySQL на основе подвыборки с несколькими возвращаемыми значениями при сохранении 500 записей для каждого уникального значения

Вот что я делаю сейчас:

DELETE FROM `dnsstats` WHERE id NOT IN 
(
SELECT id FROM 
    (
    SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.243' ORDER BY id DESC LIMIT 500 
    ) foo 
) 
AND id NOT IN 
(
SELECT id FROM 
    (
    SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.40' ORDER BY id DESC LIMIT 500 
) foo2 
) 
AND id NOT IN 
(
SELECT id FROM 
    (
    SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.50' ORDER BY id DESC LIMIT 500 
) foo3 
); 

Это прекрасно работает, но я хотел бы, чтобы выбрать отдельный IP-адрес динамически, как так:

SELECT peerhost FROM `dnsstats` GROUP BY peerhost; 

ого удалять на основе те возвращаемые значения.

Это то, что я получил от моего предыдущего вопроса:

DELETE FROM `dnsstats` WHERE id NOT IN 
(
SELECT id FROM 
    (
    SELECT id FROM `dnsstats` WHERE peerhost in (
      SELECT peerhost FROM `dnsstats` GROUP BY peerhost 
     ) ORDER BY id DESC LIMIT 500 
    ) foo 
); 

..но это оставляет меня 500 Всего записей. Я хотел бы сохранить 500 записей каждого peerhost

Любая идея, что я могу сделать, чтобы сделать эту работу? Благодаря!

Оригинальный вопрос: MySQL delete statement based on sub-select with multiple return values

+0

Справедливо, что это другой вопрос – Drew

ответ

1

Я хотел бы сделать это с помощью переменных. Ниже перечислены каждый peerhost:

select s.*, 
     (@rn := if(@ph = peerhost, @rn + 1, 
        if(@ph := peerhost, 1, 1) 
       ) 
     ) as rn 
from dnstats s cross join 
    (select @ph := '', @rn := 0) params 
order by peerhost, id desc; 

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

delete s 
    from dnstats s join 
     (select s.*, 
       (@rn := if(@ph = peerhost, @rn + 1, 
          if(@ph := peerhost, 1, 1) 
          ) 
       ) as rn 
      from dnstats s cross join 
       (select @ph := '', @rn := 0) params 
      order by peerhost, id desc 
     ) es 
     on es.id = s.id 
    where rn > 500; 

Это удаляет все, но первые 500 строк для каждого peerhost.

+0

Второе утверждение работает идеально. Спасибо, сэр! – Bryan

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

  • Нет связанных вопросов^_^