提问人:Riri 提问时间:9/6/2008 更新时间:12/8/2020 访问量:106159
从 SQL 中的数据库表中删除除前 n 之外的所有内容
Delete all but top n from database table in SQL
答:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
编辑:
Chris 提出了一个很好的性能问题,因为 TOP 10 查询将针对每一行运行。如果这是一次性的事情,那么它可能没什么大不了的,但如果这是一件常见的事情,那么我确实仔细研究了它。
评论
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)
我不知道其他风格,但MySQL DELETE允许LIMIT。
如果你可以对东西进行排序,使你想要保留的 n 行位于底部,那么你可以执行 DELETE FROM table LIMIT tablecount-n。
编辑
哎呀。我想我更喜欢 Cory Foy 的答案,假设它适用于您的情况。相比之下,我的方式感觉有点笨拙。
我会使用下面的技术来解决它。该示例需要一个每行都有一个 id 的文章表。
Delete article where id not in (select top 1000 id from article)
编辑:回答我自己的问题太慢了......
我会选择 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
评论
insert into #nuke(Nuke) ...
可能应该是: 此外,nuke这个名字令人困惑,因为您试图不删除这些行。Nuke可能是在它将被删除的事实之后命名的。insert into #nuke(NukeID) ...
重构了吗?
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
编辑:在查询分析器中尝试了它们,当前答案是快速的(该死的顺序......
更好的方法是将您想要的行插入到另一个表中,删除原始表,然后重命名新表,使其与旧表同名
评论
为那些不使用 MS SQL 的用户提供未来的参考。
在 PostgreSQL 中,使用 和 代替 .ORDER BY
LIMIT
TOP
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL——嗯......
错误 -- 此版本的 MySQL 尚不支持“LIMIT & IN/ALL/ANY/SOME 子查询'
我猜还没有。
这确实是特定于语言的,但我可能会对 SQL Server 使用如下所示的内容。
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
如果你不关心确切的行数,总有
DELETE TOP 90 PERCENT FROM dTABLE;
评论
我认为使用虚拟表会比 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
这是我是如何做到的。此方法更快、更简单:
使用 OFFSET 命令从 MS SQL 的数据库表中删除除前 n 之外的所有内容
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
替换为要排序的列。
将 number after 替换为要保留的行数。
选择或 - 任何适合您的情况。ID
OFFSET
DESC
ASC
评论
我有一个技巧可以避免对每一行执行表达式。我们可以结合以获得我们想要保留的东西。然后我们只需删除大于 的所有内容。TOP
TOP
MAX
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
评论