SQL文字列に「if句」を挿入するにはどうすればよいですか?


189

これが、MySQLデータベースで実行したいことです。

私はしたいと思います:

SELECT *
    FROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING'

それが行を返さない場合、それはで可能if(dr.HasRows == false)ですがUPDATEpurchaseOrderデータベースにを作成します。

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID'

このプロセスを少し短くするにはどうすればよいですか?


4
itemsOrderedデータベースには、呼び出される一意のIDがitemsOrdered_IDあり、繰り返しpurchaseOrder_ID値があります
John Ernest Guadalupe

1
purchaseorder一方、データベースには一意のIDがありますpurchaseOrder_ID
John Ernest Guadalupe、

回答:


408

特定のクエリに対して、次のことができます。

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID' and
          not exists (SELECT *
                      FROM itemsOrdered WHERE purchaseOrder_ID = '@purchaseOrdered_ID' AND status = 'PENDING'
                     )

しかし、あなたはより高いレベルでループしていると思います。このような値をすべて設定するには、次のことを試してください。

UPDATE purchaseOrder
    SET purchaseOrder_status = 'COMPLETED'
    WHERE not exists (SELECT 1
                      FROM itemsOrdered
                      WHERE itemsOrdered.purchaseOrder_ID = purchaseOrder.purchaseOrdered_ID AND
                            status = 'PENDING'
                      limit 1
                     )

26
実際、MySQLでは、itemsOrdered.purchaseOrder_IDにインデックスがある場合、相関サブクエリは最も効率的なアプローチの1つです。
ゴードンリノフ

8
@eggyal。。。インデックスがない場合、相関バージョンはおそらく結合よりもパフォーマンスが低いことに同意します(行の乗算などのさまざまな要因によって異なります)。ただし、インデックスを使用すると、最初の一致でインデックススキャンを停止するため、結合よりも優れているはずです。dev.mysql.com/doc/refman/5.5/en/…を確認してください。
ゴードンリノフ

53

複数テーブルUPDATE構文を使用して、ANTI-JOINbetween purchaseOrderitemsOrdered

UPDATE purchaseOrder p LEFT JOIN itemsOrdered i
    ON p.purchaseOrder_ID = i.purchaseOrder_ID
   AND i.status = 'PENDING'
SET    p.purchaseOrder_status = 'COMPLETED'
WHERE  p.purchaseOrder_ID = '@purchaseOrder_ID'
   AND i.purchaseOrder_ID IS NULL

47

MySQLはをサポートしていないためif exists(*Your condition*) (*Write your query*)、次のように記述することで「if句」を実現できます。

(*Write your insert or update query*) where not exists (*Your condition*)

27

次のクエリを使用して、レコードが存在するかどうかを確認し、それを更新することもできます。

if not exists(select top 1 fromFROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING' )
Begin

UPDATE purchaseOrder 
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID

End

22
Select FROM t1
    WHERE s11 > ANY
        (SELECT col1,col2 FROM t2
            WHERE NOT EXISTS
                (SELECT * FROM t3
                    WHERE ROW(5*t2.s1,77)=
                        (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
                            (SELECT * FROM t5) AS t5)));

4
これがどのように質問に答えるかを見るのに苦労していますか?
theMayer 2016

1
@theMayer私もですが、それはかなりいい答えです
ガブリエル

2
おめでとうございます。コードが難読化されたコードとして選択されました。
Vishwanath Dalvi

1
これは私たちが他に何ができるかの一例だと思いますSQL
トップマスター

13
if not exists(select top 1 fromFROM itemsOrdered
    WHERE purchaseOrder_ID = '@purchaseOrdered_ID'
        AND status = 'PENDING' )
Begin

UPDATE purchaseOrder 
    SET purchaseOrder_status = 'COMPLETED'
    WHERE purchaseOrder_ID = '@purchaseOrder_ID

End

7
uも回答を説明するとすばらしいでしょう。コードのみの回答は将来のユーザーには役に立ちません
Kumar Saurabh

9

SQL Server 2008の後Mergeに、単一の一致ステートメントに基づく挿入、更新、削除操作が提供された後、これを使用して参加することもできます。以下のサンプル例はあなたを助けるかもしれません。

MERGE Target AS T
USING Source AS S
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName)
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%'
    THEN DELETE 
OUTPUT $action, inserted.*, deleted.*;

このように、1つのステートメントで挿入、更新、削除を行うことができます。

詳細については、https://technet.microsoft.com/en-us/library/bb522522(v = sql.105).aspxで公式ドキュメントを参照して ください。


7

テーブルに数百万のレコードが含まれている場合、次のクエリは高速に動作します。

UPDATE PO
SET PO.purchaseOrder_status = 'COMPLETED'
FROM purchaseOrder PO
LEFT OUTER JOIN itemsOrdered IOD ON IOD.purchaseOrder_ID = PO.purchaseOrdered_ID and IOD.status = 'PENDING'
WHERE IOD.purchaseOrder_ID IS NULL

1

選択クエリで返される結果の数を保持する変数を宣言できます。この変数が0より大きい場合は、更新ステートメントを実行できます。

    Declare @ResultCount int
    SELECT @ResultCount = count(*) FROM itemsOrdered WHERE purchaseOrder_ID = '@purchaseOrdered_ID' AND status = 'PENDING'        
    If @ResultCount > 0
UPDATE purchaseOrder SET purchaseOrder_status = 'COMPLETED' WHERE purchaseOrder_ID = '@purchaseOrder_ID'        
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.