Jaki jest najlepszy sposób usunięcia wszystkich wierszy z tabeli w sql, ale pozostawienie n liczby wierszy na górze?
Odpowiedzi:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Edytować:
Chris wskazuje na dobrą wydajność, ponieważ zapytanie TOP 10 zostanie uruchomione dla każdego wiersza. Jeśli jest to jednorazowa sprawa, może to nie być taka wielka sprawa, ale jeśli jest to powszechna rzecz, przyjrzałem się temu bliżej.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)aby zmusić MySQL do utworzenia tabeli tymczasowej.
Wybrałbym kolumny ID zestaw wierszy, które chcesz zachować w tabeli tymczasowej lub zmiennej tabeli. Następnie usuń wszystkie wiersze, które nie istnieją w tabeli tymczasowej. Składnia wspomniana przez innego użytkownika:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Ma potencjalny problem. Zapytanie „SELECT TOP 10” zostanie wykonane dla każdego wiersza w tabeli, co może mieć ogromny wpływ na wydajność. Chcesz uniknąć ciągłego wykonywania tego samego zapytania.
Ta składnia powinna działać w oparciu o to, co podałeś jako oryginalną instrukcję 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) ...prawdopodobnie powinno być: insert into #nuke(NukeID) ...Również nazwa nuke jest myląca, ponieważ próbujesz NIE usunąć tych wierszy. nuke prawdopodobnie nosi nazwę po tym, że zostanie usunięty.
Przyszłe odniesienie dla użytkowników, którzy nie używają MS SQL.
W PostgreSQL użyj ORDER BYi LIMITzamiast TOP.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - cóż ...
Błąd - ta wersja MySQL nie obsługuje jeszcze „LIMIT & IN / ALL / ANY / SOME subquery”
Chyba jeszcze nie.
Myślę, że użycie wirtualnej tabeli byłoby znacznie lepsze niż klauzula IN lub tabela tymczasowa.
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
Nie wiem o innych smakach, ale MySQL DELETE dopuszcza LIMIT.
Jeśli mógłbyś tak uporządkować rzeczy, aby n wierszy, które chcesz zachować, znajdowało się na dole, możesz wykonać polecenie DELETE FROM table LIMIT tablecount-n.
Edytować
Oooo. Myślę, że bardziej podoba mi się odpowiedź Cory Foy , zakładając, że zadziała w twoim przypadku. W porównaniu z tym mój sposób wydaje się trochę niezgrabny.
To naprawdę będzie specyficzne dla języka, ale prawdopodobnie użyłbym czegoś takiego jak poniżej dla serwera SQL.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
jeśli nie zależy Ci na dokładnej liczbie wierszy, zawsze jest
DELETE TOP 90 PERCENT FROM dTABLE;
Oto jak to zrobiłem. Ta metoda jest szybsza i prostsza:
Usuń wszystkie n poza górnymi z tabeli bazy danych w MS SQL za pomocą polecenia OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Zastąp IDkolumną, według której chcesz sortować. Zastąp liczbę po OFFSETliczbie wierszy, które chcesz usunąć. Wybierz DESClub ASC- cokolwiek pasuje do Twojego przypadku.
Mam sztuczkę, aby uniknąć wykonywania TOPwyrażenia dla każdego wiersza. Możemy łączyć TOPsię, MAXaby uzyskać to, MaxIdco chcemy zachować. Następnie po prostu usuwamy wszystko większe niż 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
Uwaga: Ważne jest, aby używać go ORDER BYprzy deklarowaniu, MaxIdaby zapewnić prawidłowe wyniki.