Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete all rows except 100 most recent ones

I am using MS SQL database and I have a table named "Logs" that looks like this:

enter image description here

Records are added here one after another so the table becomes quite big after few days/weeks.

What I need to do periodically is a little bit of cleanup. I.e. I need an SQL query that would delete older rows and keep only the most recent 100 records in this table.

I agree it would be better to have it "delete records older than some_date"... It was like this before, but the client wants it different :( So... here we are.

BTW: I'm a little bit disappointed about people throwing negatives on this question. Is there something wrong with it or what?... Imagine: this question produced already 4 answers!!! ... and one guy decided to throw negative on that! Now I really don't know what to think... Strange people around here :(

like image 808
סטנלי גרונן Avatar asked Jul 06 '15 19:07

סטנלי גרונן


People also ask

How do you bulk DELETE rows in SQL?

Another way to delete multiple rows is to use the IN operator. DELETE FROM table_name WHERE column_name IN (value 1, value 2, value 3, etc...); If you want to delete all records from the table then you can use this syntax.

What is the clause to DELETE all rows from the table?

The truncate command removes all rows of a table.


2 Answers

While I agree with others that this is probably not the way to go, here's a way to do it anyway:

;WITH keepers AS
(   SELECT TOP 100 [DateTime]
    FROM dbo.Logs
    ORDER BY [DateTime] DESC )
DELETE FROM dbo.Logs a
WHERE NOT EXISTS ( SELECT 1 FROM keepers b WHERE b.[DateTime] = a.[DateTime] )
like image 186
Matt Avatar answered Sep 28 '22 02:09

Matt


You can use one of the following:

-- offset clause
WITH goners AS (
    SELECT *
    FROM Logs
    ORDER BY DateTime DESC
    OFFSET 100 ROWS 
)
DELETE FROM goners

-- numbered rows
WITH goners AS (
    SELECT ROW_NUMBER() OVER(ORDER BY DateTime DESC) AS rn, Logs.*
    FROM Logs
)
DELETE FROM goners
WHERE rn > 100

-- nth value
-- note that this "keeps" all rows that tie for last place
DELETE FROM Logs
WHERE DateTime < (
    SELECT MIN(DateTime)
    FROM (
        SELECT TOP 100 DateTime
        FROM Logs
        ORDER BY DateTime DESC
    ) AS x
)
like image 34
Salman A Avatar answered Sep 28 '22 02:09

Salman A