Який найкращий спосіб видалити всі рядки з таблиці в sql, але зберегти n кількість рядків зверху?
Відповіді:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Редагувати:
Кріс показує хороший показник ефективності, оскільки запит ТОП 10 буде виконуватися для кожного рядка. Якщо це одноразова річ, то це може бути не така велика угода, але якщо це звичайна справа, то я все-таки придивився до цього.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)щоб змусити MySQL створити тимчасову таблицю.
Я вибрав би стовпець (ідентифікатори) набору рядків, які ви хочете зберегти у тимчасовій таблиці або змінній таблиці. Потім видаліть усі рядки, які не існують у тимчасовій таблиці. Синтаксис, згаданий іншим користувачем:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Є потенційна проблема. Запит "ВИБЕРІТЬ ТОП 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 дозволяє обмежити.
Якщо ви могли впорядкувати речі так, щоб 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щоб забезпечити відповідні запити.