Wie füge ich eine 'if-Klausel' in eine SQL-Zeichenfolge ein?


188

Hier ist also, was ich in meiner MySQL- Datenbank tun möchte .

Ich möchte zu tun:

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

Wenn das keine Zeilen zurückgeben würde, was durch möglich ist if(dr.HasRows == false), würde ich jetzt eine UPDATEin der purchaseOrderDatenbank erstellen :

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

Wie könnte ich diesen Prozess etwas verkürzen?


4
Die itemsOrdered-Datenbank hat eine eindeutige ID itemsOrdered_IDund wiederkehrende purchaseOrder_IDWerte
John Ernest Guadalupe

1
Die purchaseorderDatenbank hingegen hat die eindeutige IDpurchaseOrder_ID
John Ernest Guadalupe

Antworten:


408

Für Ihre spezifische Anfrage können Sie Folgendes tun:

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'
                     )

Ich könnte jedoch vermuten, dass Sie sich auf einer höheren Ebene befinden. Versuchen Sie Folgendes, um alle diese Werte festzulegen:

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
Tatsächlich sollte in MySQL die korrelierte Unterabfrage zu den effizientesten Ansätzen gehören, vorausgesetzt, es gibt einen Index für itemsOrdered.purchaseOrder_ID.
Gordon Linoff

8
@eggyal. . . Ich bin damit einverstanden, dass die korrelierte Version ohne Index möglicherweise weniger leistungsfähig ist als der Join (hängt von verschiedenen Faktoren ab, z. B. der Multiplikation von Zeilen). Bei einem Index sollte dies jedoch besser sein als bei einem Join, da der Index-Scan bei der ersten Übereinstimmung gestoppt werden sollte. Überprüfen Sie dev.mysql.com/doc/refman/5.5/en/… .
Gordon Linoff

53

Sie können die UPDATESyntax für mehrere Tabellen verwenden , um ein ANTI-JOINZwischen- purchaseOrderund ein Ergebnis zu erzielen 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

Da MySQL nicht unterstützt if exists(*Your condition*) (*Write your query*), können Sie eine 'if-Klausel' erreichen, indem Sie wie folgt schreiben:

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

27

Sie können auch die folgende Abfrage verwenden, um zu überprüfen, ob der Datensatz vorhanden ist, und ihn dann aktualisieren:

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
Ich kämpfe darum zu sehen, wie dies die Frage überhaupt beantwortet.
theMayer

1
@ theMayer Ich auch, aber es ist eine ziemlich schöne Antwort
Gabriel

2
Herzlichen Glückwunsch, Ihr Code wurde als verschleierter Code ausgewählt.
Vishwanath Dalvi

1
Ich denke, dies ist ein Beispiel dafür, was wir sonst noch tun könnenSQL
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
Es wird großartig sein, wenn Sie die Antwort auch erklären. Nur-Code-Antworten sind für zukünftige Benutzer nicht hilfreich
Kumar Saurabh

9

Nach SQL Server 2008 Mergekönnen Sie Operationen zum Einfügen, Aktualisieren und Löschen basierend auf einer einzelnen Übereinstimmungsanweisung einfügen, mit der Sie auch beitreten können. Das folgende Beispiel könnte Ihnen helfen.

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.*;

Auf diese Weise können Sie in einer Anweisung Einfügen, Aktualisieren und Löschen.

Weitere Informationen finden Sie in den offiziellen Dokumenten unter https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx


7

Wenn die Tabelle Millionen von Datensätzen enthält, funktioniert die folgende Abfrage schnell.

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

Sie können eine Variable deklarieren, die die Anzahl der zurückgegebenen Ergebnisse bei der Auswahlabfrage enthält. Sie können dann die Update-Anweisung ausführen, wenn diese Variable größer als 0 ist

    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'        
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.