删除除最近100行之外的所有行

时间:2015-07-06 19:03:42

标签: sql sql-server tsql datetime sql-delete

我正在使用MS SQL数据库,我有一个名为" Logs"看起来像这样:

enter image description here

这里一个接一个地添加记录,所以几天/几周之后桌子会变得很大。

我需要定期做的是稍微清理一下。即我需要一个SQL查询来删除旧行,并且只保留此表中最近的100条记录。

我同意最好让它删除早于some_date的记录&#34; ...之前就是这样,但客户希望它不同:(所以......我们在这里。< / p> 顺便说一句:我对那些对这个问题不屑一顾的人感到有些失望。它有什么问题或者是什么?... 想象一下:这个问题产生了4个答案! ......一个人决定对此投反对票!现在我真的不知道该怎么想......周围的人很奇怪:(

5 个答案:

答案 0 :(得分:6)

您可以使用以下其中一项:

-- 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
)

答案 1 :(得分:3)

虽然我同意其他人认为这可能不是一条路,但无论如何,这是一种方法:

;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] )

答案 2 :(得分:3)

不要使用NOT EXISTS,只需使用>=

WITH keepers AS (
    SELECT TOP 100 [DateTime]
    FROM dbo.Logs
    ORDER BY [DateTime] DESC
   )
DELETE FROM dbo.Logs a
    WHERE l.DateTime < (SELECT MIN([DateTime]) FROM keepers);

我不确定是否存在可以在delete运行时添加新行的锁定设置。如果是这样,这仍然是安全的。

您实际上可以在SQL Server 2012 +中简化此操作:

DELETE FROM dbo.Logs a
    WHERE l.DateTime < (SELECT [DateTime] 
                        FROM dbo.logs
                        ORDER BY [DateTime]
                        OFFSET 99 FETCH FIRST 1 ROW ONLY
                       );

答案 3 :(得分:1)

这对我有用:

;with cte as(select top(select count(*) - 100 from table) * from table order by dt)
delete from cte

答案 4 :(得分:0)

DECLARE @cutoff DATETIME
SELECT TOP 100 @cutoff = [DateTime] FROM Logs ORDER BY [DateTime] DESC
DELETE FROM Logs WHERE [DateTime] < @cutoff