Qual è il modo migliore per eliminare tutte le righe da una tabella in sql ma per mantenere il numero n di righe in alto?
Risposte:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Modificare:
Chris segnala un buon rendimento in quanto la query TOP 10 verrà eseguita per ogni riga. Se questa è una cosa una tantum, potrebbe non essere un grosso problema, ma se è una cosa comune, l'ho esaminata più da vicino.
Selezionare le colonne ID l'insieme di righe che si desidera mantenere in una tabella temporanea o in una variabile di tabella. Quindi elimina tutte le righe che non esistono nella tabella temporanea. La sintassi menzionata da un altro utente:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Ha un potenziale problema. La query "SELECT TOP 10" verrà eseguita per ogni riga della tabella, il che potrebbe essere un enorme calo delle prestazioni. Vuoi evitare di ripetere la stessa query più e più volte.
Questa sintassi dovrebbe funzionare, in base a ciò che hai elencato come istruzione SQL originale:
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) ...
probabilmente dovrebbe essere: insert into #nuke(NukeID) ...
Anche il nome nuke è fonte di confusione perché stai cercando di NON eliminare queste righe. nuke prende probabilmente il nome dal fatto che verrà cancellato.
Riferimento futuro per coloro che non utilizzano MS SQL.
In PostgreSQL usa ORDER BY
e LIMIT
invece di TOP
.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - beh ...
Errore : questa versione di MySQL non supporta ancora "LIMIT & IN / ALL / ANY / SOME subquery"
Non ancora, credo.
Penso che l'utilizzo di una tabella virtuale sarebbe molto meglio di una clausola IN o di una tabella temporanea.
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
Non conosco altri sapori ma MySQL DELETE consente LIMIT.
Se potessi ordinare le cose in modo che le n righe che vuoi mantenere siano in fondo, allora potresti fare un DELETE FROM table LIMIT tablecount-n.
modificare
Oooo. Penso che la risposta di Cory Foy mi piaccia di più, ammesso che funzioni nel tuo caso. La mia strada sembra un po 'goffa al confronto.
Questo sarà davvero specifico della lingua, ma probabilmente userò qualcosa di simile al seguente per SQL Server.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
se non ti interessa il numero esatto di righe, c'è sempre
DELETE TOP 90 PERCENT FROM dTABLE;
Ecco come l'ho fatto. Questo metodo è più veloce e più semplice:
Elimina tutto tranne i primi n dalla tabella del database in MS SQL utilizzando il comando OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Sostituisci ID
con la colonna in base alla quale desideri ordinare. Sostituisci il numero dopo OFFSET
con il numero di righe che desideri mantenere. Scegli DESC
o ASC
- qualunque cosa si adatti al tuo caso.
Il modo migliore sarebbe inserire le righe che vuoi in un'altra tabella, rilasciare la tabella originale e quindi rinominare la nuova tabella in modo che abbia lo stesso nome della vecchia tabella
Ho un trucco per evitare di eseguire l' TOP
espressione per ogni riga. Possiamo combinare TOP
con MAX
per ottenere la MaxId
vogliamo mantenere. Quindi cancelliamo semplicemente tutto ciò che è maggiore di 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 utilizzare ORDER BY
durante la dichiarazione MaxId
per garantire che vengano richiesti risultati corretti.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)
per forzare MySQL a creare una tabella temporanea.