Какой лучший способ удалить все строки из таблицы в sql, но сохранить n строк вверху?
Ответы:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Редактировать:
Крис показывает хорошее снижение производительности, поскольку запрос TOP 10 будет выполняться для каждой строки. Если это разовая вещь, то, возможно, это не такая уж большая проблема, но если это обычная вещь, то я действительно присмотрелся к ней.
Я бы выбрал столбцы идентификаторов - набор строк, которые вы хотите сохранить во временной таблице или табличной переменной. Затем удалите все строки, которых нет во временной таблице. Синтаксис, упомянутый другим пользователем:
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
insert into #nuke(Nuke) ...вероятно, должно быть: insert into #nuke(NukeID) ...Также имя nuke сбивает с толку, потому что вы пытаетесь НЕ удалить эти строки. 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.
Еще не думаю.
Я думаю, что использование виртуальной таблицы было бы намного лучше, чем предложение IN или временная таблица.
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 DELETE позволяет LIMIT.
Если бы вы могли упорядочить вещи так, чтобы n строк, которые вы хотите сохранить, находились внизу, вы могли бы выполнить УДАЛЕНИЕ ИЗ таблицы LIMIT tablecount-n.
редактировать
Оооо. Я думаю, что мне больше нравится ответ Кори Фоя , если он работает в вашем случае. По сравнению с этим мой путь кажется немного неуклюжим.
Это действительно будет зависеть от языка, но я бы, вероятно, использовал что-то вроде следующего для SQL-сервера.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
если вам не важно точное количество строк, всегда есть
DELETE TOP 90 PERCENT FROM dTABLE;
Вот как я это сделал. Этот способ быстрее и проще:
Удалите все, кроме верхнего n, из таблицы базы данных в MS SQL с помощью команды OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Замените IDстолбцом, по которому вы хотите отсортировать. Заменить номер послеOFFSET числом строк, которые вы хотите сохранить. Выберите DESCили ASC- что подходит для вашего случая.
У меня есть трюк, чтобы не выполнять TOPвыражение для каждой строки. Мы можем комбинировать TOPс, MAXчтобы получить то, MaxIdчто хотим сохранить. Затем мы просто удаляем все, что больше 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
Примечание: это важно использовать ORDER BYпри объявлении, MaxIdчтобы обеспечить запрос правильных результатов.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)чтобы заставить MySQL создать временную таблицу.