SQL Serverのトップ100レコードを更新する方法


393

SQL Serverの上位100件のレコードを更新したい。T1フィールドF1とのテーブルがありF2ます。T1200件のレコードがあります。F1上位100件のレコードのフィールドを更新したい。TOP 100SQL Serverに基づいて更新するにはどうすればよいですか?

回答:


684

かっこはUPDATEステートメントに必要です。

update top (100) table1 set field1 = 1

28
order by同様に使用する方法はありますか?
ジョーフィリップス

8
@JoePhilllips注文にはMartin Smithの回答を使用してください
jjxtra

ただし、これらは上位100件のレコードではなく、単に100件の任意に選択されたレコードです。トップ100には、レコードをランク​​付けするためのいくつかの順序が含まれます。
Thorsten Kettner 2017

1
これは「尋ねられたとおり」の質問に答えますが、TOPはなんらかの順序なしでは意味がありません(そして予測できません)。マーティン・スミスによるさらに下の答えを見てください。
Andy G

1
ところで:括弧は重要です!
Simon_Weaver

300

ORDER BY全体のアイデアがなければ、TOPあまり意味がありません。topの概念が意味を持つためには、どちらの方向が「上」であり、どちらが「下」であるかの一貫した定義が必要です。

それにもかかわらず、SQL Serverはそれを許可しますが、確定的な結果を保証しません

UPDATE TOP受け入れられた回答の構文はORDER BY句をサポートしていませんが、CTEまたは派生テーブルを使用して目的のソート順を以下のように定義することにより、ここで確定的なセマンティクスを取得することが可能です。

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'

71
あなたは無意味だと言いますが、それは真実ではありません。/通常/、TOPオッズを使用しているときは、それを使用する必要があることを認めます。ORDER BYなぜなら、興味があるのは何かの「最も」または「最も」のようなものだからです。ただし、一致するレコードを1つだけ取得する場合もあります。今日のように!データの問題(サイクル)を1つずつ修正する必要がありました。修正プロセス全体には、dbスクリプト、一部のユーザー介入、および一部のアプリケーション操作が含まれていました。どのレコードが最初に処理されるかは問題ではありませんでした。一度に1つずつ処理することを気にしました。
MetaFight 2012年

17
@MetaFightしかし、その場合WHERE、以前に処理されたレコードを除外する句があったでしょう。書かれ、受け入れられた答えとしての質問はかなり意味がありません。ところで、テーブルをキューとして使用する場合、これは非常に便利なリンクです
Martin Smith

10
非同期プロセスを実行できるようにするため、order byなしでtopを使用する必要があります。where句には、既に処理されたものは含まれませんが、一度に処理できる数は多くありません。したがって、完全に有効なユースケースがあります。
ジェフデイビス

4
@Martin Smith:バッチで更新したいとします。たとえば、一度に10000を更新します。これは良い使い方のようで、順序は関係ありません。これはどのように「意味をなさない」のですか?
Jay Sullivan

5
@notfedこれは、上記のコメントですでに死亡について説明されているのと同じケースです。その場合のクエリは、受け入れられた回答のクエリのように見えませんか?where同じ行を何度も処理しないようにする句が必要です。
マーティン・スミス

14

まだSQL Server 2000にこだわっているような人のSET ROWCOUNT {number};ために、UPDATEクエリの前に使用できます

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;

更新を100行に制限します

少なくともSQL 2005以降は非推奨になっていますが、SQL 2017でも機能します。 https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017


1
SET ROWCOUNTは、トリガーと更新されるコマンドに影響します。カスケード削除セットがある場合、子テーブルに子行の行数を超える数が存在すると、トランザクションが失敗する可能性があります。
EricI 2017年

そうは言っても、SET ROWCOUNT @RowCountParameter; は有効な構文ですが、SELECT TOP @RowCountParamter * FROM TableNameは無効です。更新される行を構成する必要がある場合は、カスケード削除が有効になっている子テーブルがない限り、SET ROWCOUNT#が現在の方が適切なオプションです。
EricI 2017年

SQL Serverの2017年に、TOP句で@Variableを使用できるようになりました:docs.microsoft.com/en-us/sql/t-sql/queries/...
アレクサンドルZarubkin

13
update tb set  f1=1 where id in (select top 100 id from tb where f1=0)

4

さらに優れているのは、インラインのテーブル値関数を使用して、TOP更新する行(およびviaの数)を選択できることです。あれは:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

テーブル値関数の場合、次のように更新する行を選択する興味深いものがあります。

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

...そして、(私の考えでは)選択された上位の行のみを決定論的に更新すると同時に、UPDATEステートメントの構文を簡略化する真の力があります。



0

エイリアスと結合を使用して選択から更新することもできます。

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.