Làm cách nào để xóa 1000 hàng trên cùng khỏi bảng bằng Sql Server 2008?


108

Tôi có một bảng trong SQL Server. Tôi muốn xóa 1000 hàng trên cùng khỏi nó. Tuy nhiên, tôi đã thử điều này, nhưng tôi thay vì chỉ xóa 1000 hàng trên cùng, nó đã xóa tất cả các hàng trong bảng.

Đây là mã:

delete from [mytab] 
select top 1000 
a1,a2,a3
from [mytab]

8
Bạn cần ĐẶT HÀNG BẰNG CÁCH để làm cho TOP có ý nghĩa: hãy xem câu trả lời của @Martin Smith, đây là câu trả lời duy nhất trong năm câu trả lời này. Tôi tuyệt vọng đôi khi
GBN

2
Bạn có muốn xóa bất kỳ 1000 hàng? Chỉ được chọn ngẫu nhiên? Hoặc, ví dụ, hàng đầu 1000 hàng cũ nhất?
Nick Chammas

13
Bạn đã xóa tất cả bảng vì delete from [mytab]là một câu lệnh và select top ...là một câu lệnh khác.
Nick Chammas

2
Bạn không cần đặt hàng để lên hàng đầu, phụ thuộc vào lý do tại sao bạn đang lên TOP. Nếu bạn cần xóa 10 triệu hàng và có sẵn 1 GB dung lượng nhật ký, hãy sử dụng Xóa TOP (10000) Từ dbo.myTable (với mệnh đề lựa chọn của bạn) và tiếp tục chạy nó cho đến khi không còn hàng nào để xóa. Ai quan tâm nếu nó tùy tiện. Sắp xếp chỉ làm chậm truy vấn.
tvanharp

1
Tôi nhận ra rằng đây là một câu hỏi cổ (trong những năm SO) nhưng tôi nghĩ rằng điều quan trọng là mọi người nên xem xét các nhận xét của @gbn . Mặc dù nhận xét của anh ấy không áp dụng cho tình huống nhất định của tôi (cố gắng xóa các khối bản ghi mà không gây ra vấn đề KHÓA nhưng không thực sự quan tâm đến thứ tự xóa chúng) thì chúng rất có thể áp dụng cho tình huống CỦA BẠN. Hãy chắc chắn rằng bạn đã cân nhắc chúng trước khi sử dụng một cách mù quáng các câu trả lời không bao gồm mệnh đề ORDER BY dưới đây.
Andrew Steitz

Câu trả lời:


196

Đoạn mã bạn đã thử thực tế là hai câu lệnh. A DELETEtheo sau là a SELECT.

Bạn không xác định được TOPthứ tự theo thứ gì.

Đối với một tiêu chí sắp xếp cụ thể, xóa khỏi CTE hoặc biểu thức bảng tương tự là cách hiệu quả nhất.

;WITH CTE AS
(
SELECT TOP 1000 *
FROM [mytab]
ORDER BY a1
)
DELETE FROM CTE

13
Đối với những người tự hỏi tại sao bạn không thể làm được DELETE TOP (1000) FROM table ORDER BY column, hãy đọc phần này : "Các hàng được tham chiếu trong biểu thức TOP được sử dụng với INSERT, UPDATE, MERGE hoặc DELETE không được sắp xếp theo bất kỳ thứ tự nào."
Nick Chammas

3
@Magnus vâng. Tuy nhiên, không phải 2000. Có thể sử dụng bảng dẫn xuất vào năm 2000. Tôi không có phiên bản nào để kiểm tra.
Martin Smith


2
Tôi đã làm theo một cách hơi khác (mặc dù tôi nghĩ CTE có thể đẹp hơn khi nhìn vào): XÓA T1 TỪ (CHỌN HÀNG ĐẦU 1000 * TỪ [MYTAB] ĐẶT HÀNG THEO A1) T1;
Abacus

4
@Liam - chỉ vì nếu có bất kỳ tuyên bố nào trước CTE thì điều này cần được kết thúc bằng dấu chấm phẩy để thêm nó vào trước các WITHkhiếu nại từ những người chưa làm điều đó.
Martin Smith

86

Có thể tốt hơn cho sql2005 + sử dụng:

DELETE TOP (1000)
FROM [MyTab]
WHERE YourConditions

Đối với Sql2000:

DELETE FROM [MyTab]
WHERE YourIdField IN 
(
  SELECT TOP 1000 
    YourIdField 
  FROM [MyTab]
  WHERE YourConditions
)

NHƯNG

Nếu bạn muốn xóa tập hợp con cụ thể của các hàng thay vì tập hợp con tùy ý, bạn nên chỉ định rõ ràng thứ tự cho truy vấn con:

DELETE FROM [MyTab]
WHERE YourIdField IN 
(
  SELECT TOP 1000 
    YourIdField 
  FROM [MyTab]
  WHERE YourConditions
  ORDER BY ExplicitSortOrder
)

Cảm ơn tp @gbn đã đề cập và yêu cầu câu trả lời rõ ràng và chính xác hơn.


3
@gbn Có thể vô ích đối với bạn, nhưng đó vẫn là chính xác những gì câu hỏi đang yêu cầu.
Joachim Isaksson

1
@Joachim Isaksson: hãy đọc về TOP rồi quay lại. Không có thứ gọi là TOP mà không có ORDER BY trong bộ. Ngoài ra, hãy tìm cho tôi một tài liệu tham khảo chính tắc chứng minh tôi đã sai ... Để tiết kiệm cho bạn khi tìm kiếm, sqlblog.com/blogs/alexander_kuznetsov/archive/2009/05/20/…blogs.technet.com/b/wardpond/archive / 2007/07/19 /…
gbn

1
@gbn Không bất kỳ điều kiện về MÀ hàng để xóa, vì vậy ORDER BY trong subquery là vô ích
Oleg Dok

1
@gbn Bạn đã đề cập đến WHERE trong truy vấn con - Tôi lọc 1000 hàng tùy ý bên trong chọn tiêu chí và xóa sau đó. Kịch bản hợp lệ? Đúng. Nếu tôi thêm ORDER BY NEWID () hoặc bất cứ điều gì nó thay đổi gì - tôi vẫn xóa 1.000 dòng lọc theo các tiêu chí choosen
Oleg Dok

8
@gbn Trong trường hợp bạn đang tìm cách sử dụng hợp lệ TOP mà không cần ĐẶT HÀNG BẰNG CÁCH: điều đưa tôi đến đây là tôi cần xóa tất cả các hàng phù hợp với một số tiêu chí nhưng vì lý do hiệu suất, tôi không muốn nó xóa hơn 10.000 hàng tại một thời điểm. Tôi không quan tâm nó sẽ xóa những hàng nào, vì tôi sẽ chạy lại lệnh vào khoảng thời gian nào đó cho đến khi tất cả các hàng như vậy biến mất.
Richiban


6
delete from [mytab]
where [mytab].primarykeyid in
(
select top 1000 primarykeyid
from [mytab]
)

4
Vô ích: TOP mà không có một ORDER BY mang đến cho hàng tùy ý
GBN

4
@gbn Có thể vô ích đối với bạn, nhưng đó vẫn là chính xác những gì câu hỏi đang yêu cầu.
Joachim Isaksson

3
@gbn Tôi không khẳng định rằng có bất kỳ thứ tự sắp xếp mặc định nào hoặc truy vấn thậm chí hữu ích theo bất kỳ cách nào, tôi chỉ nhắc bạn rằng câu hỏi không yêu cầu một thứ tự, vì vậy bạn sẽ đề xuất sắp xếp theo cách nào?
Joachim Isaksson

2
@gbn Tôi không biết tại sao bạn rất thù địch với mọi người về một số thứ là điểm xuất phát. Tôi không khẳng định rằng câu trả lời của tôi là kết thúc tất cả, nó chỉ đơn thuần là một gợi ý để giúp đỡ ai đó. Tôi nghĩ rằng điều quan trọng là các khóa quay trở lại từ truy vấn phụ ở đây.
Jason Dam

2
Đây có thể là tất cả những gì người hỏi đang tìm kiếm. Tôi chỉ thêm một ghi chú cho những người khác đang đọc để nhấn mạnh rằng các hàng bị xóa bởi một tuyên bố như vậy không được đảm bảo theo bất kỳ thứ tự nào.
Nick Chammas

3
SET ROWCOUNT 1000;

DELETE FROM [MyTable] WHERE .....

2
Khi xử lý chỉ với 1000 hàng, nó có thực sự quan trọng không ?? Nếu nó là 100.000.000 hàng thì điểm của bạn có thể có giá trị, nhưng đối với chỉ 1.000 dòng, đây là bởi đến nay các giải pháp đơn giản nhất đề xuất cho đến nay cho SQL 2008.
Joe Bourne

1

Nó nhanh. Thử nó:

DELETE FROM YourTABLE
FROM (SELECT TOP XX PK FROM YourTABLE) tbl
WHERE YourTABLE.PK = tbl.PK

Thay thế YourTABLEbằng tên bảng, XXbằng một số, ví dụ: 1000, pklà tên của trường khóa chính trong bảng của bạn.


Bạn đang tạo hiệu quả hai bảng từ một bảng, sau đó xóa nơi đã kết hợp. Nó hoạt động tốt khi bạn muốn xóa các bản ghi cũ nhất (hoặc mới nhất) khỏi bảng, vì bạn có thể sắp xếp chúng tăng dần trước. T-sql này được Microsoft chấp nhận (và nó rất nhanh).
Tequila
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.