11

I have a script that runs every hour on my php site. In that script I would like some kind of MySQL query to delete every record from a table but say the latest 50.

How would I do something like that?

// pseudo code: like this?
DELETE from chat WHERE id = max (ID - 50) 
Brian Tompsett - 汤莱恩
  • 5,438
  • 68
  • 55
  • 126
user1022585
  • 12,121
  • 19
  • 53
  • 74
  • Can you add a timestamp field to your table? – O.O Jan 16 '12 at 20:47
  • If your ID column is an identity column with autoincrement of 1, you could do somthing like that: `DELETE FROM chat WHERE ID NOT IN(SELECT TOP 50 ID FROM chat ORDER BY ID DESC)` – pistipanko Jan 16 '12 at 20:51
  • In this case use: `DELETE FROM chat WHERE datecol NOT IN(SELECT TOP 50 datecol FROM chat ORDER BY datecol DESC)-- SQL Server` `DELETE FROM chat WHERE datecol NOT IN(SELECT datecol FROM chat ORDER BY datecol DESC LIMIT 50) --MySQL` – pistipanko Jan 16 '12 at 20:57
  • @user1022585 - I think you should delete based on a time span (between x and x), rather than the number of records. Is there some reason why it has to be the last 50, rather than a time period/span? – O.O Jan 16 '12 at 21:01
  • `#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'` – user1022585 Jan 16 '12 at 21:02
  • possible duplicate of [SQL query: Delete all records from the table except latest N?](http://stackoverflow.com/questions/578867/sql-query-delete-all-records-from-the-table-except-latest-n) – e-sushi Nov 23 '13 at 03:43

3 Answers3

19

You could try using NOT IN:

EDIT for MySQL:

DELETE FROM chat WHERE id NOT IN ( 
  SELECT id 
  FROM ( 
    SELECT id 
    FROM chat 
    ORDER BY id DESC 
    LIMIT 50
  ) x 
); 

This is for SQL-Server:

DELETE FROM chat WHERE id NOT IN 
    (SELECT TOP 50 id FROM chat ORDER BY id DESC)  

Assuming higher values of id are always newer.

Brissles
  • 3,805
  • 22
  • 31
2

NOT IN is inefficient. You can slightly modify the first option in the previous answer by @Mithrandir to make it look like this:

DELETE from chat WHERE id < 
  (SELECT id FROM 
    (SELECT id FROM chat ORDER BY id DESC LIMIT 50) t ORDER BY id ASC LIMIT 1));
esp
  • 7,537
  • 5
  • 46
  • 73
0

You could try something like this:

DELETE from chat WHERE id < (SELECT max(ID)-50 FROM chat) 

This would work if your values for ID are incremented in steps of 1. Or you can use something like:

DELETE FROM chat WHERE id NOT IN 
    (SELECT id FROM ( SELECT ID FROM chat ORDER BY datetime_col DESC LIMIT 50) t ) -- mysql
Mithrandir
  • 23,979
  • 6
  • 45
  • 64