2012-12-21 11 views
135

Oto, co chcę zrobić w mojej bazie danych MySQL.Jak umieścić "klauzula if" w ciągu SQL?

Chciałbym:

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

Jeśli to nie zwraca żadnych wierszy, co jest możliwe dzięki if(dr.HasRows == false), chciałbym teraz utworzyć UPDATE w bazie purchaseOrder:

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

Jak będzie Czy mogę uczynić ten proces nieco krótszym?

+4

baza itemsOrdered ma unikatowy identyfikator o nazwie 'itemsOrdered_ID' i powtarzające' purchaseOrder_ID' wartości –

+1

Opcja 'bazie purchaseorder' drugiej strony ma unikatowy identyfikator' purchaseOrder_ID' –

Odpowiedz

288

dla konkretnego zapytania, można zrobić:

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

Jednak mogę się domyślać, że jesteś zapętlenie na wyższym poziomie. Aby ustawić wszystkie takie wartości, spróbuj tego:

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 
        ) 
+18

Właściwie w MySQL, skorelowane podkwerendy powinny należeć do najbardziej wydajnych podejść, zakładając, że istnieje indeks na itemsOrdered.purchaseOrder_ID. –

+5

@eggyal. . . Zgadzam się, że bez indeksu wersja skorelowana jest prawdopodobnie mniej wydajna niż sprzężenie (zależy od różnych czynników, takich jak mnożenie wierszy). Jednak z indeksem powinien być lepszy niż sprzężenie, ponieważ powinien zatrzymać skanowanie indeksu przy pierwszym dopasowaniu. Sprawdź http://dev.mysql.com/doc/refman/5.5/en/subquery-optimization-with-exists.html. –

41

Można użyć Multiple-table UPDATE składni do skutku ANTI-JOIN między purchaseOrder i 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 
37

Ponieważ MySQL nie obsługuje if exists(*Your condition*) (*Write your query*), ty może osiągnąć 'if clause' pisząc tak:

(*Write your insert or update query*) where not exists (*Your condition*) 
14
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))); 
+3

Staram się zobaczyć, jak to w ogóle odpowiada na pytanie? – theMayer

+1

@ theMayer Me też, ale to całkiem niezła odpowiedź – Gabriel

18

Można także skorzystać z następującej kwerendy w celu sprawdzenia, czy rekord istnieje i następnie zaktualizować go:

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 
6
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 
+6

będzie świetnie, jeśli wyjaśnisz odpowiedź również, odpowiedzi tylko kodu nie są pomocne dla przyszłych użytkowników –