从SQL中的数据库表中删除除前n之外的所有内容

时间:2008-09-05 17:46:34

标签: sql

从sql中的表中删除所有行但是在顶部保留n行的最佳方法是什么?

11 个答案:

答案 0 :(得分:69)

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)

修改:

自从每行运行TOP 10查询以来,Chris带来了良好的性能提升。如果这是一次性的事情,那么它可能没那么大,但如果它是一个普通的事情,那么我确实看得更近了。

答案 1 :(得分:30)

我会选择要保存在临时表或表变量中的行集的ID列。然后删除临时表中不存在的所有行。其他用户提到的语法:

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)

有潜在的问题。将对表中的每一行执行“SELECT TOP 10”查询,这可能是一个巨大的性能损失。您希望避免一遍又一遍地进行相同的查询。

根据您列为原始SQL语句的内容,此语法应该有效:

create table #nuke(NukeID int)

insert into #nuke(Nuke) select top 1000 id from article

delete article where not exists (select 1 from nuke where Nukeid = id)

drop table #nuke

答案 2 :(得分:10)

未使用MS SQL的未来参考资料。

在PostgreSQL中使用ORDER BYLIMIT代替TOP

DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);

MySQL - 好吧......

  

错误 - 此版本的MySQL尚不支持'LIMIT&   IN / ALL / ANY / SOME子查询'

还没猜到。

答案 3 :(得分:4)

我认为使用虚拟表会比IN子句或临时表好得多。

DELETE 
    Product
FROM
    Product
    LEFT OUTER JOIN
    (
        SELECT TOP 10
            Product.id
        FROM
            Product
    ) TopProducts ON Product.id = TopProducts.id
WHERE
    TopProducts.id IS NULL

答案 4 :(得分:2)

我不了解其他口味,但MySQL DELETE允许LIMIT。

如果你可以订购东西,以便你想要保留的n行位于底部,那么你可以做一个DELETE FROM表LIMIT tablecount-n。

修改

呜。我想我更喜欢Cory Foy's回答,假设它适用于您的情况。相比之下,我的方式感觉有点笨拙。

答案 5 :(得分:1)

这确实是特定于语言的,但我可能会使用类似以下内容的SQL服务器。

declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable

如果你不关心确切的行数,总会有

DELETE TOP 90 PERCENT FROM dTABLE;

答案 6 :(得分:1)

这就是我的做法。此方法更快,更简单:

使用OFFSET命令从MS SQL的数据库表中删除除topn以外的所有内容

WITH CTE AS
    (
    SELECT  ID
    FROM    dbo.TableName
    ORDER BY ID DESC
    OFFSET 11 ROWS
    )
DELETE CTE;

ID替换为要排序的列。 将OFFSET之后的数字替换为要删除的行数。 选择DESCASC-适合您的情况。

答案 7 :(得分:0)

我会用下面的技术解决它。该示例期望每行都有一个带有 id 文章表。

Delete article where id not in (select top 1000 id from article)

编辑:回答我自己的问题太慢了......

答案 8 :(得分:0)

重构?

Delete a From Table a Inner Join (
    Select Top (Select Count(tableID) From Table) - 10) 
        From Table Order By tableID Desc
) b On b.tableID = A.tableID

编辑:在查询分析器中尝试了它们,目前的答案是禁食的(该死的命令......)

答案 9 :(得分:0)

更好的方法是将您想要的行插入另一个表中,删除原始表,然后重命名新表,使其与旧表具有相同的名称

答案 10 :(得分:0)

我有一个技巧,可以避免对每一行执行TOP表达式。我们可以将TOPMAX结合起来得到我们想要保留的MaxId。然后,我们只删除大于MaxId的所有内容。

-- Declare Variable to hold the highest id we want to keep. 
DECLARE @MaxId as int = (
SELECT MAX(temp.ID)
FROM (SELECT TOP 10 ID FROM table ORDER BY ID ASC) temp
)

-- Delete anything greater than MaxId. If MaxId is null, there is nothing to delete.
IF @MaxId IS NOT NULL
    DELETE FROM table WHERE ID > @MaxId

注意:在声明ORDER BY时使用MaxId很重要,以确保查询正确的结果。