2008-09-05 7 views

Antwort

61
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table) 

Edit:

Chris eine gute Leistung Hit bringt, da die TOP 10 Abfrage für jede Zeile ausgeführt werden würde. Wenn das eine einmalige Sache ist, dann ist es vielleicht nicht so groß, aber wenn es etwas Gemeinsames ist, dann habe ich es genauer betrachtet.

+3

Wenn jemand normalerweise alle bis auf die obersten n Zeilen löschen möchte, würde ich argumentieren, dass sie größere Probleme haben, um die sie sich kümmern müssen. –

+4

Nur ein Hinweis, dass Sie das Leistungsproblem der Unterabfrage lösen können, indem Sie entweder eine temporäre Tabelle manuell erstellen (vorausgesetzt, es handelt sich um eine seltene Operation) oder die Abfrage schreiben als 'DELETE FROM Tabelle WHERE ID NICHT IN (SELECT ID VON (SELECT TOP 10 ID VON Tabelle) AS x) 'um MySQL zu zwingen, eine temporäre Tabelle zu erstellen. –

+0

Danke. Das war ein Lebensretter :) – Si8

2

Ich weiß nicht, über andere Aromen, aber MySQL DELETE ermöglicht LIMIT.

Wenn Sie die Dinge bestellen können, so dass die n Zeilen, die Sie am unteren Rande sind behalten wollen, dann könnten Sie ein FROM Tabelle LIMIT Table-n löschen.

bearbeiten

Oooo. Ich denke, ich mag Cory Foy's besser antworten, vorausgesetzt, es funktioniert in Ihrem Fall. Mein Weg fühlt sich im Vergleich ein wenig klobig an.

0

Ich würde es mit der folgenden Technik lösen. Das Beispiel erwartet eine Artikel Tabelle mit einem id in jeder Zeile.

Delete article where id not in (select top 1000 id from article) 

Edit: Zu langsam meine eigene Frage zu beantworten ...

29

Ich würde ID-Spalte (n) auswählen, die Menge der Zeilen, die Sie in eine temporäre Tabelle oder Tabellenvariable behalten möchten. Löschen Sie dann alle Zeilen, die in der temporären Tabelle nicht vorhanden sind. Die Syntax von einem anderen Benutzer erwähnt:

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table) 

Hat ein potenzielles Problem. Die "SELECT TOP 10" -Abfrage wird für jede Zeile in der Tabelle ausgeführt, was ein großer Leistungseinbruch sein könnte. Sie möchten vermeiden, die gleiche Abfrage immer wieder zu machen.

sollten Diese Syntax arbeiten, basiert, was Sie als Ihre ursprüngliche SQL-Anweisung aufgeführt:

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 
+2

'Einfügen in #nuke (Nuke) ...' sollte wahrscheinlich sein: 'Einfügen in #nuke (NukeID) ...' Auch der Name Nuke ist verwirrend, weil Sie versuchen, diese Zeilen NICHT zu löschen. Nuke wird wahrscheinlich nach der Tatsache benannt, dass es gelöscht wird. –

0

Überarbeitete ?

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 

edit: versuchte, sie beide in dem Query Analyzer wird aktuelle Antwort (verdammt, um durch ...) gefastet

0

besseren Weg wäre, um die Zeilen einfügen Sie in einer anderen Tabelle wollen, die Original-Tabelle löschen und dann die neue Tabelle umbenennen, damit es den gleichen Namen wie die alte Tabelle für die Nutzungs

+0

Warum ist das besser? Schneller? Benötigt ein paar zusätzliche Befehle, um dies zu erreichen. – MeanGreen

6

zukünftige Referenz hat, die nicht MS SQL verwenden.

Verwenden Sie in PostgreSQL ORDER BY und LIMIT anstelle von TOP.

DELETE FROM table 
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n); 

MySQL - gut ...

Fehler - Diese Version von MySQL unterstützt noch nicht 'LIMIT & IN/ALL/ANY/SOME Unterabfrage'

Noch nicht, denke ich.

1

Dies wird wirklich sprachspezifisch sein, aber ich würde wahrscheinlich so etwas wie folgt für SQL Server verwenden.

declare @n int 
SET @n = SELECT Count(*) FROM dTABLE; 
DELETE TOP (@n - 10) FROM dTable 

, wenn Sie nicht über die genaue Anzahl der Zeilen ist es egal, gibt es immer

DELETE TOP 90 PERCENT FROM dTABLE; 
+1

Keine von beiden funktioniert. Die Frage fragt, wie nur die obersten N Zeilen in einer Tabelle beibehalten werden. Beide Beispiele behalten nur die unteren N Zeilen bei. – Chris

+0

Funktioniert gut in MSSQL. Fügen Sie einfach eine Sortierung hinzu, um den unteren anstelle des oberen zu löschen. – MeanGreen

2

Ich denke, eine virtuelle Tabelle verwenden wäre viel besser als eine IN-Klausel oder 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 
Verwandte Themen