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

Rir*_*iri 78 sql

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

Cor*_*Foy 73

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Run Code Online (Sandbox Code Playgroud)

编辑:

自从每行运行TOP 10查询以来,Chris带来了良好的性能提升.如果这是一次性事情,那么它可能没有那么大的交易,但如果它是一个普通的事情,那么我确实仔细观察它.

  • 如果有人通常需要删除除前n行之外的所有行,我认为他们有更大的问题需要担心. (4认同)
  • 只需注意您可以通过手动创建临时表(假设这是一个不常见的操作)或将查询写为`DELETE FROM Table WHERE ID NOT IN(SELECT id FROM(SELECT TOP 10 ID FROM Table)来解决子查询性能问题)AS x)`强制MySQL创建临时表. (4认同)
  • @ Daniel Schaffer听起来他们没有任何数据库或业务逻辑问题.听起来像是一个完全正常的保留政策. (3认同)

Chr*_*ler 31

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

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Run Code Online (Sandbox Code Playgroud)

有潜在的问题.将对表中的每一行执行"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
Run Code Online (Sandbox Code Playgroud)

  • `插入到#nuke(Nuke)......`应该是:`插入#nuke(NukeID)...`同样名称nuke令人困惑,因为你试图不删除这些行.nuke可能以它将被删除的事实命名. (2认同)

Sim*_*urr 11

对于不使用MS SQL的用户的未来参考.

在PostgreSQL中使用ORDER BYLIMIT不是TOP.

DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
Run Code Online (Sandbox Code Playgroud)

MySQL - 好吧......

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

还没猜到.


Har*_*vey 11

我是这样做的。这种方法更快更简单:

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

WITH CTE AS
    (
    SELECT  ID
    FROM    dbo.TableName
    ORDER BY ID DESC
    OFFSET 11 ROWS
    )
DELETE CTE;
Run Code Online (Sandbox Code Playgroud)

替换ID为您要排序的列。将后面的数字替换OFFSET为您要保留的行数。选择DESCASC- 任何适合您的情况。


Tim*_*son 5

我认为使用虚拟表比使用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
Run Code Online (Sandbox Code Playgroud)