ฉันจะใส่ 'if clause' ในสตริง SQL ได้อย่างไร


190

ดังนั้นนี่คือสิ่งที่ฉันต้องการทำในฐานข้อมูลMySQLของฉัน

ฉันอยากจะทำ:

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

หากที่จะไม่กลับแถวใด ๆ ซึ่งเป็นไปได้ผ่านif(dr.HasRows == false)ตอนนี้ฉันจะสร้างUPDATEในpurchaseOrderฐานข้อมูล:

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
จอห์นเออร์เนสกัวดาลู

คำตอบ:


410

สำหรับแบบสอบถามเฉพาะของคุณคุณสามารถทำได้:

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
Gordon Linoff

8
@eggyal . . ฉันยอมรับว่าหากไม่มีดัชนีเวอร์ชันที่สัมพันธ์กันอาจมีประสิทธิภาพน้อยกว่าการเข้าร่วม (ขึ้นอยู่กับปัจจัยต่าง ๆ เช่นการคูณแถว) ด้วยดัชนีแม้ว่ามันควรจะดีกว่าการเข้าร่วมเพราะมันควรหยุดการสแกนดัชนีในนัดแรก ตรวจสอบdev.mysql.com/doc/refman/5.5/en/...
Gordon Linoff

53

คุณสามารถใช้UPDATEไวยากรณ์หลายตารางเพื่อให้มีผลANTI-JOINระหว่างpurchaseOrderและitemsOrdered:

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 clause' โดยเขียนดังนี้:

(*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

1
@theMayer ฉันเกินไป แต่มันเป็นคำตอบที่ดีงาม
กาเบรียล

2
ขอแสดงความยินดีรหัสของคุณถูกเลือกเป็นรหัสที่สับสน
Vishwanath Dalvi

1
ฉันเดาว่านี่เป็นตัวอย่างของสิ่งที่เราสามารถทำได้โดยใช้SQL
Top-Master

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 อธิบายคำตอบยังรหัสคำตอบเดียวที่จะไม่เป็นประโยชน์สำหรับผู้ใช้ในอนาคต
มาร์ 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.*;

เช่นนี้คุณสามารถแทรกอัปเดตและลบในคำสั่งเดียว

และสำหรับข้อมูลเพิ่มเติมคุณสามารถอ้างอิงเอกสารอย่างเป็นทางการได้ที่ 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.