8

みなさん、良い一日を。SQL ステートメントについて質問したいと思います。SQL Server 2008 を使用しており、Workflow Transaction というテーブルがあります。このテーブルには、12 のレコードがあります。下の写真は表の内容です。

ここに画像の説明を入力

私はこのSQL文を持っています:

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] IN
(
    SELECT [RequestId]
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
    AND RequestId = 3
)

私の目的は、OrderNumber が最大値より小さいリクエスト ID を更新することです。これは、WHERE 句内の SELECT ステートメントからの出力になります。ここで、更新されるレコードは、上記のレコードのみになると予想しています (コードでは、RequestId # 3 です)。

実際に起こったことは、更新されたレコードが 4 つだけではなく、5 つになりました! 既存の SQL ステートメントに問題はありますか?

4

3 に答える 3

6

問題は、RequestId = 3 ですべてのレコードの更新を行っていることです。サブクエリの結果が3関連するすべてのレコードを更新することになることを考慮してください。

あなたのクエリは do と同等です

UPDATE Workflow_Txn 
SET Status = 1
WHERE RequestId = 3

クエリを必要以上に複雑にする理由があるかどうかはわかりません。もっと単純なものでうまくいくように思えます

UPDATE Workflow_Txn 
SET    Status = 1
WHERE  [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
       AND RequestId = 3
于 2013-07-23T13:20:23.050 に答える
6

クエリの問題は、サブクエリが非常に詳細になり、注文番号が最大未満のレコードを見つけることです。そして、同じリクエスト (最大注文数を含む) を持つすべてのものを選択します。

次のように CTE を使用してこれを修正することをお勧めします。

with toupdate as (
      select t.*,
             MAX(OrderNumber) as MaxON
      from Workflow_txn
      where RequestId = 3
     )
UPDATE toupdate
    SET Status = 1
    where OrderNumber < MaxON;

CTE を個別に実行して、どのレコードが更新される可能性があるかを確認できるため、この構造が気に入っています。

クエリを修正するには、リクエストを using に変更し、次OrderNumberを繰り返しますRequestId = 3

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] = 3 and
      OrderNumber in
(
    SELECT [OrderNumber]
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)      
    AND RequestId = 3
)
于 2013-07-23T13:20:54.783 に答える
4

サブクエリは 3 の RequestID を返すと言ったので、その ID ですべてのリクエストを更新しました。それを通り抜けます。あなたが探していたと思うのは次のようなものでした:

UPDATE Workflow_Txn 
SET Status = 1
WHERE [RequestId] = 3
AND  [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3) 
于 2013-07-23T13:22:39.467 に答える