2013-08-07 36 views
2

我的表中有一個TIME場。正確的方法來刪除「舊的」行

我想只保留5個最新的行。

我可以在不使用SELECT的情況下刪除舊的行嗎?

我覺得邏輯應該是這樣的:

DELETE FROM tbl WHERE row_num > 5 ORDER BY TIME 

我怎樣才能在MySQL實現這個whitout使用SELECT得到TIME值列表?

+0

你的問題不清楚。先把它做好。 – ripa

+2

加上'LIMIT 5,999999'這個查詢。而也有,而不是'ASC'(默認)'ORDER BY TIME DESC'。 [查看類似的問題與相同的非優雅的答案。](http://stackoverflow.com/questions/255517/mysql-offset-infinite-rows) –

+0

由於它被寫入所有大寫,是'TIME'一詞指的是一個實際你的表的列 - 或者它是某種佔位符? –

回答

3

沒有正確的ORDER BY子句,必須將SQL結果集視爲無序的

您必須提供一個列來顯式存儲您的行序號。這可能是表格的時間戳或auto_increment列。

請記住,您也可以同時訪問您的表格。如果其他人在刪除時插入,應該是預期的行爲?至於我可以告訴這個,你只保留了「5個最新行」可能導致局勢+「那些插在其它事務」。


如果你有你的表目的和PRIMARY KEY(或其他UNIQUE NOT NULL列)time欄你可以寫:

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k 
    ON (tbl.pk) = (k.pk) 
    WHERE k.`time` IS NULL; 

如果你有複合主鍵(a,b)你可以寫:

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k 
    ON (tbl.a,tbl.b) = (k.a,k.b) 
    WHERE k.tm IS NULL; 
+0

他已經有時間場了。我同意這有潛在的競爭條件。 – Paul

+0

@Paul我不太確定,因爲它拼寫所有大寫像保留的關鍵字... –

+0

假設時間或時間是每行的時間戳,我更關心的是MySQL DELETE的文檔有裸露LIMIT(例如LIMIT 3)之後的數字而不是窗口(例如LIMIT 10,15)。因此限制5,10000000000可能無效。 http://dev.mysql.com/doc/refman/5.7/en/delete.html – Paul

0
DELETE FROM TBL 
    WHERE ROW_NUM = (SELECT ROW_NUM FROM TBL LIMIT 6, 99999) 
    ORDER BY TIME DESC; 

這將從刪除記錄6,7,8,9,10,...,200005

由於LIMIT範圍這裏爲6〜9999記錄開始時,是指200005

+0

你肯定ROW_NUM的刪除,並選擇將代表同一行? –

0

如果要排除的前5行,使用類似:

DELETE FROM table WHERE primary_key IN 
(SELECT primary_key FROM table LIMIT 1 OFFSET 5,1000000) 

100000可能是一個非常大的不

+0

你應該將'*'更改爲'primary_key'嗎? –

0

也許這將是一個另類:

DELETE FROM tbl 
WHERE primary_key NOT IN (SELECT primary_key 
          FROM tbl 
          ORDER BY time 
          DESC LIMIT 5) 
相關問題