Was ist der beste Weg, um alle Zeilen aus einer Tabelle in SQL zu löschen, aber n Zeilen oben zu halten?
Antworten:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Bearbeiten:
Chris bringt einen guten Leistungstreffer hervor, da die TOP 10-Abfrage für jede Zeile ausgeführt wird. Wenn dies eine einmalige Sache ist, dann ist es vielleicht keine so große Sache, aber wenn es eine übliche Sache ist, dann habe ich es mir genauer angesehen.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x), um MySQL zu zwingen, eine temporäre Tabelle zu erstellen.
Ich würde ID-Spalte (n) der Reihe von Zeilen auswählen, die Sie in einer temporären Tabelle oder Tabellenvariablen behalten möchten. Löschen Sie dann alle Zeilen, die in der temporären Tabelle nicht vorhanden sind. Die von einem anderen Benutzer erwähnte Syntax:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Hat ein potentielles Problem. Die Abfrage "SELECT TOP 10" wird für jede Zeile in der Tabelle ausgeführt, was einen großen Leistungseinbruch bedeuten könnte. Sie möchten vermeiden, dass immer wieder dieselbe Abfrage durchgeführt wird.
Diese Syntax sollte funktionieren, basierend auf dem, was Sie als Ihre ursprüngliche SQL-Anweisung aufgeführt haben:
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) ...sollte wohl sein: insert into #nuke(NukeID) ...Auch der Name nuke ist verwirrend, weil Sie versuchen, diese Zeilen NICHT zu löschen. nuke ist wahrscheinlich nach der Tatsache benannt, dass es gelöscht wird.
Zukünftige Referenz für Benutzer, die kein MS SQL verwenden.
Verwenden Sie in PostgreSQL ORDER BYund LIMITanstelle von TOP.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - na ja ...
Fehler - Diese Version von MySQL unterstützt die Unterabfrage 'LIMIT & IN / ALL / ANY / SOME' noch nicht.
Noch nicht, denke ich.
Ich denke, die Verwendung einer virtuellen Tabelle wäre viel besser als eine IN-Klausel oder eine temporäre Tabelle.
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
Ich weiß nichts über andere Geschmacksrichtungen, aber MySQL DELETE erlaubt LIMIT.
Wenn Sie die Dinge so bestellen könnten, dass die n Zeilen, die Sie behalten möchten, unten sind, könnten Sie eine DELETE FROM-Tabelle LIMIT tablecount-n ausführen.
Bearbeiten
Oooo. Ich denke, ich mag Cory Foys Antwort besser, vorausgesetzt, es funktioniert in Ihrem Fall. Mein Weg fühlt sich im Vergleich etwas klobig an.
Dies wird wirklich sprachspezifisch sein, aber ich würde wahrscheinlich Folgendes für SQL Server verwenden.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
Wenn Sie sich nicht für die genaue Anzahl der Zeilen interessieren, gibt es immer
DELETE TOP 90 PERCENT FROM dTABLE;
Hier ist, wie ich es gemacht habe. Diese Methode ist schneller und einfacher:
Löschen Sie alle bis auf das oberste n aus der Datenbanktabelle in MS SQL mit dem Befehl OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Ersetzen Sie IDdurch eine Spalte, nach der Sie sortieren möchten. Ersetzen Sie die Nummer nach OFFSETdurch die Anzahl der Zeilen, die Sie löschen möchten. Wählen Sie DESCoder ASC- was auch immer zu Ihrem Fall passt.
Besser wäre es, die gewünschten Zeilen in eine andere Tabelle einzufügen, die ursprüngliche Tabelle zu löschen und die neue Tabelle so umzubenennen, dass sie denselben Namen wie die alte Tabelle hat
Ich habe einen Trick, um zu vermeiden, dass der TOPAusdruck für jede Zeile ausgeführt wird. Wir können kombinieren TOPmit MAXdem bekommen MaxIdwir behalten wollen. Dann löschen wir einfach alles größer als 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
Hinweis: Es ist wichtig, ORDER BYbei der Deklaration MaxIdzu verwenden , um sicherzustellen, dass die richtigen Ergebnisse abgefragt werden.