47


11

理想的にはこれをやりたいです。

UPDATE TOP(10)メッセージSET status = 10 WHERE status = 0 ORDER BY priority DESC;

英語で:私はDBからトップ10の利用可能な(status = 0)メッセージを取得し、それらをロックしたい(status = 10)。 優先順位の高いメッセージが最初に取得されます。

残念ながら、MS SQLではこの更新ではorder by句を使用できません。

とにかくこれを回避する方法?

5 回答


93


WITH q AS(SELECT TOP 10 *メッセージからWHEREステータス= 0 ORDER BY優先順位DESC)UPDATE q SETステータス= 10


43


最初に上位10位のIDを優先度順に取得してから、その副照会にあるIDを更新する副照会を行うことができます。

更新メッセージSET status = 10 WHERE ID in(SELECT TOP(10)Id FROM Table WHERE status = 0 ORDER BY priority DESC);


2


私はこれをより良いアプローチとして提供しなければなりません - あなたはいつもアイデンティティ分野の贅沢を持っているわけではありません:

UPDATE m
SET [status]=10
FROM (
  Select TOP (10) *
  FROM messages
  WHERE [status]=0
  ORDER BY [priority] DESC
) m

複数のテーブルを結合するなど、サブクエリを複雑にすることもできます。

なぜこれがいいの? `+ messages +`テーブルのIDフィールド(または他の一意の列)の存在に依存しません。 たとえそのテーブルに一意のキーがまったくない場合でも、任意のテーブルから上位N行を更新するために使用できます。


1


更新メッセージSET status = 10 WHERE ID in(SELECT TOP(10)Id FROM Table WHERE status = 0 ORDER BY priority DESC);


0


下記のコメントで説明されているように、SET ROWCOUNT句を使用することもできますが、それはSQL Server 2014以前のものに限られます。

SET ROWCOUNT 10

更新メッセージSET status = 10 WHERE status = 0

SET ROWCOUNT 0

詳細情報:http://msdn.microsoft.com/ja-jp/library/ms188774.aspx

または一時テーブル付き

DECLARE @t TABLE(id INT)INSERT @t(id)メッセージの先頭10個のidから選択WHERE status = 0 ORDER BY priority DESC

更新メッセージSET status = 10 WHERE ID IN(SELECT ID FROM @t)