Cách tốt nhất để xóa tất cả các hàng khỏi bảng trong sql nhưng vẫn giữ n số hàng trên cùng là gì?
Câu trả lời:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Biên tập:
Chris mang lại hiệu suất tốt vì truy vấn TOP 10 sẽ được chạy cho mỗi hàng. Nếu đây là chuyện chỉ xảy ra một lần, thì nó có thể không phải là vấn đề lớn, nhưng nếu nó là một điều phổ biến, thì tôi đã xem xét kỹ hơn về nó.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)
để buộc MySQL tạo một bảng tạm thời.
Tôi sẽ chọn (các) cột ID tập hợp các hàng mà bạn muốn giữ vào bảng tạm thời hoặc biến bảng. Sau đó, xóa tất cả các hàng không tồn tại trong bảng tạm thời. Cú pháp được đề cập bởi một người dùng khác:
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Có một vấn đề tiềm ẩn. Truy vấn "CHỌN HÀNG ĐẦU 10" sẽ được thực thi cho mỗi hàng trong bảng, đây có thể là một lần truy cập hiệu suất rất lớn. Bạn muốn tránh lặp đi lặp lại cùng một truy vấn.
Cú pháp này sẽ hoạt động, dựa trên những gì bạn đã liệt kê dưới dạng câu lệnh SQL ban đầu của mình:
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) ...
có lẽ nên là: insert into #nuke(NukeID) ...
Ngoài ra, tên nuke gây nhầm lẫn vì bạn đang cố KHÔNG xóa các hàng này. nuke có lẽ được đặt tên theo thực tế là nó sẽ bị xóa.
Tài liệu tham khảo trong tương lai cho những người sử dụng không sử dụng MS SQL.
Trong PostgreSQL sử dụng ORDER BY
và LIMIT
thay vì TOP
.
DELETE FROM table
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - tốt ...
Lỗi - Phiên bản MySQL này chưa hỗ trợ 'LIMIT & IN / ALL / ANY / SOME subquery'
Tôi đoán là chưa.
Tôi nghĩ rằng sử dụng một bảng ảo sẽ tốt hơn nhiều so với một mệnh đề IN hoặc bảng tạm thời.
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
Tôi không biết về các hương vị khác nhưng MySQL DELETE cho phép LIMIT.
Nếu bạn có thể sắp xếp mọi thứ sao cho n hàng bạn muốn giữ ở dưới cùng, thì bạn có thể thực hiện XÓA khỏi bảng LIMIT số lượng bảng-n.
Biên tập
Ồ! Tôi nghĩ rằng tôi thích câu trả lời của Cory Foy hơn, giả sử nó hoạt động trong trường hợp của bạn. Cách của tôi cảm thấy hơi rắc rối khi so sánh.
Đây thực sự là ngôn ngữ cụ thể, nhưng tôi có thể sẽ sử dụng một cái gì đó như sau cho máy chủ SQL.
declare @n int
SET @n = SELECT Count(*) FROM dTABLE;
DELETE TOP (@n - 10 ) FROM dTable
nếu bạn không quan tâm đến số lượng hàng chính xác, luôn có
DELETE TOP 90 PERCENT FROM dTABLE;
Đây là cách tôi đã làm điều đó. Phương pháp này nhanh hơn và đơn giản hơn:
Xóa tất cả trừ n đầu khỏi bảng cơ sở dữ liệu trong MS SQL bằng lệnh OFFSET
WITH CTE AS
(
SELECT ID
FROM dbo.TableName
ORDER BY ID DESC
OFFSET 11 ROWS
)
DELETE CTE;
Thay thế ID
bằng cột mà bạn muốn sắp xếp. Thay thế số sau OFFSET
bằng số hàng mà bạn muốn xóa. Chọn DESC
hoặc ASC
- bất cứ điều gì phù hợp với trường hợp của bạn.
Đã tái cấu trúc?
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
chỉnh sửa: đã thử cả hai trong trình phân tích truy vấn, câu trả lời hiện tại được nhanh chóng (thứ tự chết tiệt bởi ...)
Tôi có một mẹo để tránh thực thi TOP
biểu thức cho mọi hàng. Chúng tôi có thể kết hợp TOP
với MAX
để có được những thứ MaxId
chúng tôi muốn giữ. Sau đó, chúng tôi chỉ cần xóa mọi thứ lớn hơn 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
Lưu ý: Điều quan trọng là sử dụng ORDER BY
khi khai báo MaxId
để đảm bảo kết quả phù hợp được truy vấn.