2016-10-04 45 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個總記錄。我想保留每個的記錄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