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

问题描述 投票:3回答:5

我正在使用MS SQL数据库,我有一个名为“Logs”的表,如下所示:

记录一个接一个地添加到这里,所以几天/几周后表变得非常大。

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

我同意最好让它“删除早于some_date的记录”......之前就是这样,但客户希望它与众不同:(所以......我们在这里。

顺便说一句:我对那些对这个问题不屑一顾的人有点失望。它有什么问题或者是什么?...想象一下:这个问题产生了4个答案! ......一个人决定对此投反对票!现在我真的不知道该怎么想......周围的人很奇怪:(

sql sql-server tsql datetime sql-delete
5个回答
7
投票

您可以使用以下之一:

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

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

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

1
投票

这对我有用:

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

0
投票
DECLARE @cutoff DATETIME
SELECT TOP 100 @cutoff = [DateTime] FROM Logs ORDER BY [DateTime] DESC
DELETE FROM Logs WHERE [DateTime] < @cutoff
© www.soinside.com 2019 - 2024. All rights reserved.