Sql Server 2008 kullanılarak bir tablodan ilk 1000 satır nasıl silinir?


108

SQL Server'da bir tablom var. İlk 1000 satırı ondan silmek istiyorum. Ancak bunu denedim, ancak ben sadece ilk 1000 satırı silmek yerine tablodaki tüm satırları sildim.

İşte kod:

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

8
TOP'u anlamlı kılmak için bir ORDER BY'a ihtiyacınız var: @Martin Smith'in cevabına bakın, buna sahip olan beş kişiden yalnızca biri. Bazen umutsuzluğa
kapılıyorum

2
Silmek istediğiniz musunuz herhangi 1000 satır? Sadece rastgele mi seçildiniz? Veya, örneğin, ilk 1000 en eski satır?
Nick Chammas

13
Tüm tabloyu sildiniz çünkü delete from [mytab]bir ifade ve select top ...başka bir ifadedir .
Nick Chammas

2
Üst için sipariş vermenize gerek yok, neden TOP yaptığınıza bağlı. 10 milyon satırı kaldırmanız gerekiyorsa ve 1 GB günlük alanınız varsa, TOP (10000) dbo.myTable'dan Sil'i kullanın (seçme cümlesiyle) ve silinecek satır kalmayıncaya kadar çalıştırmaya devam edin. Keyfi olup olmadığı kimin umurunda. Sıralama yalnızca sorguyu yavaşlatır.
tvanharp

1
Bunun çok eski bir soru olduğunun farkındayım (SO yıllarında) ama insanların @gbn'nin yorumlarını dikkate almasının önemli olduğunu düşünüyorum . Yorumları benim durumum için geçerli olmasa da (KİLİT sorunlarına neden olmadan kayıt bloklarını silmeye çalışmak, ancak silindikleri sırayı gerçekten önemsememek), SİZİN durumunuz için büyük olasılıkla geçerli olabilir. ORDER BY cümlesi içermeyen aşağıdaki cevapları körü körüne kullanmadan önce bunları göz önünde bulundurduğunuzdan emin olun.
Andrew Steitz

Yanıtlar:


196

Denediğiniz kod aslında iki ifadedir. A ve DELETEardından a SELECT.

TOPNeye göre sıralı olarak tanımlamazsınız .

Belirli bir sıralama kriteri için bir CTE'den veya benzer bir tablo ifadesinden silmek en etkili yoldur.

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

13
Yapamayacağınız neden merak edenler için DELETE TOP (1000) FROM table ORDER BY column, bu okuma : "INSERT ile kullanıldığında TOP ifadesinde başvurulan satırlar, GÜNCELLEME, BIRLEŞTIRME veya DELETE herhangi bir sırada düzenlenmiş değildir."
Nick Chammas

3
@Magnus evet. Ama 2000 değil. 2000 yılında türetilmiş bir tablo kullanmak mümkün olabilir. Etrafta test edebileceğim bir örnek yok.
Martin Smith


2
Biraz farklı bir yol yapmıştım (CTE'nin daha iyi bakabileceğini düşünüyorum): T1'İ SİL ([MYTAB ]'DAN A1'E GÖRE TOP 1000 * SEÇİN) T1;
Abacus

4
@Liam - çünkü CTE'den önce herhangi bir ifade varsa, bunun noktalı virgülle sonlandırılması gerekir, böylece bunu WITHyapmamış insanlardan gelen şikayetlerin önüne ekleyerek .
Martin Smith

86

Sql2005 + için aşağıdakileri kullanmak daha iyi olabilir:

DELETE TOP (1000)
FROM [MyTab]
WHERE YourConditions

Sql2000 için:

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

FAKAT

Rastgele alt küme yerine belirli satır alt kümesini silmek istiyorsanız, alt sorgu için sırayı açıkça belirtmelisiniz:

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

Daha net ve kesin cevaptan bahsettiğiniz ve talep ettiğiniz için tp @gbn'ye teşekkür ederiz.


3
@gbn Belki sizin için işe yaramaz, ama yine de sorunun sorduğu şey bu.
Joachim Isaksson

1
@Joachim Isaksson: Gidin ve TOP hakkında okuyun ve sonra geri gelin. Setlerde ORDER BY olmadan TOP diye bir şey yoktur. Alternatif olarak, gidip bana yanlış olduğunu kanıtlayan kanonik bir referans bulun ... Sizi aramadan kurtarmak için, sqlblog.com/blogs/alexander_kuznetsov/archive/2009/05/20/… ve blogs.technet.com/b/wardpond/archive /
2007/07/19

1
alt sorgu işe yaramaz içinde SİPARİŞ BY böylece satır silmek HANGİ hakkında herhangi koşulları Hayır @gbn
Oleg Dok

1
@gbn Alt sorguda WHERE'den bahsettiniz mi - Seçtiğiniz kriterler içindeki 1000 rastgele satırı filtreliyorum ve sonra siliyorum. Geçerli senaryo? Evet. ORDER BY NEWID () eklersem veya hiçbir şeyi değiştirmezsem - yine de seçilen kriterlere göre filtrelenmiş 1000 satırı silerim
Oleg Dok

8
@gbn ORDER BY olmadan TOP'un geçerli bir kullanımını arıyorsanız: beni buraya getiren şey, bazı kriterlere uyan tüm satırları silmem gerekti, ancak performans nedenleriyle 10.000'den fazla satırı silmesini istemiyorum zamanında. Hangi satırları sildiği umurumda değil, çünkü tüm bu satırlar gidene kadar komutu belirli aralıklarla tekrar çalıştıracağım.
Richiban


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

4
İşe

4
@gbn Belki sizin için işe yaramaz, ama yine de sorunun sorduğu şey bu.
Joachim Isaksson

3
@gbn Herhangi bir varsayılan sıralama düzeni olduğunu veya sorgunun herhangi bir şekilde yararlı olduğunu iddia etmedim, sadece soruyu sormadığını hatırlattım, bu yüzden ne sipariş vermeyi önerirsiniz?
Joachim Isaksson

2
@gbn Başlangıç ​​noktası olan bir şey yüzünden neden herkese bu kadar düşmanca davrandığınızı bilmiyorum. Cevabımın her şeyin sonu olduğunu iddia etmiyorum, sadece birine yardım etmek için bir öneri. Buradaki alt sorgudan gelen anahtarların önemi olduğunu düşünüyorum.
Jason Dam

2
Soruyu soranın aradığı tek şey bu olabilir. Böyle bir ifade ile silinen satırların herhangi bir sırayla olmasının garanti edilmediğini vurgulamak için okuyan başkalarına bir not ekleyeceğim.
Nick Chammas

3
SET ROWCOUNT 1000;

DELETE FROM [MyTable] WHERE .....

2
Sadece 1000 sıra ile uğraşırken, gerçekten önemli mi? 100.000.000 satır olsaydı, puanlarınız geçerli olabilir, ancak yalnızca 1000 satır için, bu şimdiye kadar SQL 2008 için önerilen en basit çözümdür.
Joe Bourne

1

O hızlı. Dene:

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

1000 gibi bir sayı ile YourTABLEtablo adına göre değiştirin , tablonuzun birincil anahtar alanının adıdır.XXpk


Etkili bir şekilde iki tablo oluşturuyorsunuz ve ardından birleştirildiği yeri siliyorsunuz. Bir tablodaki en eski (veya en yeni) kayıtları silmek istediğinizde iyi çalışır, çünkü bunları önce artan şekilde sıralayabilirsiniz. Bu t-sql Microsoft tarafından kabul edilir (ve hızlıdır).
Tequila
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.