SQL Server 2008を使用してテーブルから上位1000行を削除する方法


108

SQL Serverにテーブルがあります。上位1000行を削除したいと思います。ただし、これを試しましたが、上位1000行を削除するだけでなく、テーブル内のすべての行を削除しました。

これがコードです:

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

8
TOPを意味のあるものにするには、ORDER BYが必要です。@ Martin Smithの回答を参照してください。これは、5つのうちの1つだけです。私は時々絶望します
gbn '21 / 01/12

2
削除したいですか任意の 1000行を?ランダムに選択しただけですか?または、たとえば、最も古い1000個の最も古い行?
Nick Chammas

13
delete from [mytab]は1つのステートメントであり、select top ...別のステートメントであるため、すべてのテーブルを削除しました。
Nick Chammas

2
TOPを注文する必要はありません。TOPを行う理由によって異なります。1,000万行を削除する必要があり、1 GBのログ領域を利用できる場合は、(select句を使用して)Delete TOP(10000)From dbo.myTableを使用し、削除する行がなくなるまで実行し続けます。それが恣意的であるかどうかは気にしない。並べ替えはクエリの速度を低下させるだけです。
tvanharp

1
これは古くからの質問であることはわかっいますが(SO年では)、@ gbnのコメントを人々が検討することが重要だと思います。彼のコメントは私の与えられた状況には当てはまりませんが(LOCKの問題を引き起こさずにレコードのブロックを削除しようとしますが、削除される順序にはあまり注意を払っていません)、あなたの状況に当てはまる可能性が高いです。ORDER BY句を含まない以下の回答を盲目的に利用する前に、それらを検討してください。
Andrew Steitz 2016

回答:


195

あなたが試みたコードは実際には2つのステートメントです。AのDELETE後にSELECT

あなたはTOP何によって注文されたと定義しません。

特定の順序付け基準では、CTEまたは類似のテーブル式から削除するのが最も効率的な方法です。

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

13
なぜできないのか疑問に思う方はDELETE TOP (1000) FROM table ORDER BY column、「INSERT、UPDATE、MERGE、またはDELETEで使用されるTOP式で参照される行が、どのような順序でも配置されていない」とお読みください
Nick Chammas

3
@マグナスはい。2000年ではありません。2000年に派生テーブルを使用できる可能性があります。テストするインスタンスはありません。
マーティン・スミス


2
私は少し異なる方法を実行しました(ただし、CTEの方が見やすいと思います)。DELETET1 FROM(SELECT TOP 1000 * FROM [MYTAB] ORDER BY A1)T1;
そろばん2014

4
@Liam-CTEの前に前のステートメントがある場合、これはセミコロンで終了する必要があるので、それをWITH行っていない人々からの先取りの苦情の前にそれを追加する必要があります。
マーティン・スミス

86

sql2005 +を使用する方がよい場合があります。

DELETE TOP (1000)
FROM [MyTab]
WHERE YourConditions

Sql2000の場合:

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

だが

任意のサブセットではなく特定の行のサブセットを削除する場合は、サブクエリの順序を明示的に指定する必要があります。

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

より明確で正確な回答について言及および要求してくださったtp @gbnに感謝します。


3
@gbn多分役に立たないかもしれませんが、それでも問題はまさにそれを求めています。
Joachim Isaksson 2012年

1
@Joachim Isaksson:TOPについて読んでから、戻ってきてください。セットにORDER BYがなければ、TOPなどはありません。または、私が間違っていることを証明する正規の参照を見つけてください...検索を保存するには、sqlblog.com / blogs /
2007/07/19

1
@gbn削除するWHICH行に関する条件がないため、サブクエリのORDER BYは役に立たない
Oleg Dok

1
@gbnサブクエリでWHEREについて言及しましたか-私は選択した基準内の1000の任意の行をフィルタリングしてから削除します。有効なシナリオ?はい。ORDER BY NEWID()または何も変更しないものを追加した場合-選択した基準でフィルターされた1000行を削除します
Oleg Dok

8
@gbn ORDER BYなしでTOPの有効な使用を探している場合:ここで私をもたらしたのは、いくつかの基準に一致するすべての行を削除する必要があるが、パフォーマンス上の理由から、10,000行を超えて削除したくない一度に。削除する行は気にしません。そのような行がすべてなくなるまで、一定の間隔でコマンドを再度実行するためです。
リチバン2014年


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

4
役に立たない:ORDER BYのないTOPは任意の行を与える
gbn

4
@gbn多分役に立たないかもしれませんが、それでも問題はまさにそれを求めています。
Joachim Isaksson 2012年

3
@gbnデフォルトの並べ替え順があるとか、クエリがなんらかの意味で便利だとか言っていませんが、質問では並べ替えを要求していないので、何を並べたらいいですか?
Joachim Isaksson 2012年

2
@gbn出発点となる何かをめぐって、なぜあなたがみんなに対してそれほど敵対的であるのか、私にはわかりません。私の答えがすべてであるとは主張していません。誰かを助けるための提案にすぎません。重要なのは、ここのサブクエリから返されるキーだと思います。
ジェイソンダム

2
これは、質問者が探しているすべてのことかもしれません。そのようなステートメントによって削除された行が任意の順序であることが保証されていないことを強調するために、他の人が読んでいるメモを追加します。
Nick Chammas

3
SET ROWCOUNT 1000;

DELETE FROM [MyTable] WHERE .....

2
1000行だけを扱う場合、それは本当に重要ですか?それは100,000,000行だった場合、あなたのポイントは有効かもしれませんが、ちょうど1000行のために、これが最も簡単な解決策は、SQL 2008のために、これまでに提案された、これまでである
ジョーボーン

1

速いです。それを試してみてください:

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

YourTABLEテーブル名で 置き換えるXX、たとえば1000などの数字 pkは、テーブルの主キーフィールドの名前です。


1つから2つのテーブルを効果的に作成し、結合された場所を削除します。最初に昇順でソートできるため、テーブルから最も古い(または最新の)レコードを削除する場合に役立ちます。このt-sqlはMicrosoftによって受け入れられています(しかも高速です)。
テキーラ2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.