Qual é a melhor maneira de excluir todas as linhas de uma tabela no sql, mas manter n número de linhas no topo?
Respostas:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Editar:
Chris traz um bom resultado de desempenho, já que a consulta TOP 10 seria executada para cada linha. Se for uma coisa única, então pode não ser tão importante, mas se for uma coisa comum, então eu olhei mais de perto.
Eu selecionaria ID coluna (s) o conjunto de linhas que você deseja manter em uma tabela temporária ou variável de tabela. Em seguida, exclua todas as linhas que não existem na tabela temporária. A sintaxe mencionada por outro usuário:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Tem um problema potencial. A consulta "SELECT TOP 10" será executada para cada linha da tabela, o que pode ser um grande impacto no desempenho. Você deseja evitar fazer a mesma consulta repetidamente.
Essa sintaxe deve funcionar, com base no que você listou como sua instrução SQL original:
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) ...provavelmente deveria ser: insert into #nuke(NukeID) ...Além disso, o nome nuke é confuso porque você está tentando NÃO deletar essas linhas. nuke é provavelmente nomeado após o fato de que será excluído.
Referência futura para quem não usa MS SQL.
No PostgreSQL, use ORDER BYe em LIMITvez de TOP.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - bem ...
Erro - Esta versão do MySQL ainda não suporta subconsulta 'LIMIT & IN / ALL / ANY / SOME'
Acho que ainda não.
Acho que usar uma tabela virtual seria muito melhor do que uma cláusula IN ou uma tabela temporária.
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
Não sei sobre outros sabores, mas o MySQL DELETE permite LIMIT.
Se você pudesse ordenar as coisas de forma que as n linhas que deseja manter fiquem no final, você poderia fazer um DELETE FROM tabela LIMIT tablecount-n.
Editar
Oooo. Acho que gosto mais da resposta de Cory Foy , presumindo que funcione no seu caso. Meu caminho parece um pouco desajeitado em comparação.
Isso realmente vai ser específico do idioma, mas provavelmente usaria algo como o seguinte para o servidor SQL.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
se você não se preocupa com o número exato de linhas, sempre há
DELETE TOP 90 PERCENT FROM dTABLE;
Aqui está como eu fiz. Este método é mais rápido e simples:
Exclua tudo, exceto n superior da tabela de banco de dados em MS SQL usando o comando OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Substitua IDpela coluna pela qual você deseja classificar. Substitua o número a seguir OFFSETpelo número de linhas que deseja manter. Escolha DESCou ASC- o que for adequado ao seu caso.
A melhor maneira seria inserir as linhas que você deseja em outra tabela, remover a tabela original e então renomear a nova tabela para que tenha o mesmo nome da tabela antiga
Eu tenho um truque para evitar a execução da TOPexpressão para cada linha. Podemos combinar TOPcom MAXpara obter o MaxIdque queremos manter. Então nós simplesmente apagar tudo maior do que 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
Nota: É importante usar ORDER BYao declarar MaxIdpara garantir que os resultados adequados sejam consultados.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)para forçar o MySQL a criar uma tabela temporária.