Удалить все, кроме top n из таблицы базы данных в SQL


каков наилучший способ удалить все строки из таблицы в sql, но сохранить n строк сверху?

9 71
sql

9 ответов:

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

Edit:

Крис приносит хороший хит производительности, так как топ-10 запрос будет выполняться для каждой строки. Если это одноразовая вещь, то это может быть не так важно, но если это обычная вещь, то я посмотрел на нее ближе.

Я бы выбрал столбец(ы) ID набор строк, которые вы хотите сохранить в временной таблице или переменной таблицы. Затем удалите все строки, которые не существуют во временной таблице. Синтаксис, упомянутый другим пользователем:

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

есть потенциальная проблема. Запрос "SELECT TOP 10" будет выполнен для каждой строки в таблице, что может стать огромным ударом по производительности. Вы хотите избежать повторения одного и того же запроса снова и снова.

этот синтаксис должен работать, основываясь на том, что вы указан в качестве исходного оператора 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

будущая ссылка для тех, кто использует, кто не использует MS SQL.

в PostgreSQL используйте ORDER BY и LIMIT вместо TOP.

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

MySQL -- ну...

-- эта версия MySQL еще не поддерживает 'LIMIT & IN/ALL / ANY / SOME subquery'

пока не думаю.

Я думаю, что использование виртуальной таблицы было бы намного лучше, чем в предложении или временной таблице.

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

Я не знаю о других вкусах, но MySQL удалить позволяет ограничить.

Если бы вы могли заказать вещи так, чтобы n строк, которые вы хотите сохранить, были внизу, то вы могли бы удалить из таблицы LIMIT tablecount-n.

Edit

Оооо. Я думаю, что мне нравится Кори Фой ответьте лучше, предполагая, что это работает в вашем случае. Мой путь кажется немного неуклюжим по сравнению.

Это действительно будет специфичным для языка, но я бы, вероятно, использовал что-то вроде следующего для SQL server.

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

Если вы не заботитесь о точном количестве строк, всегда есть

DELETE TOP 90 PERCENT FROM dTABLE;

Я бы решил его, используя технику ниже. Пример ожидать статьи С id на каждой строке.

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

изменить: слишком медленно, чтобы ответить на мой собственный вопрос ...

рефакторинг?

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: попробовал их обоих в анализаторе запросов, текущий ответ постится(проклятый порядок...)

лучше было бы вставить строки, которые вы хотите в другую таблицу, отбросить исходную таблицу, а затем переименовать новую таблицу, чтобы она имела то же имя, что и старая таблица