Làm cách nào để đặt 'mệnh đề if' trong chuỗi SQL?


189

Vì vậy, đây là những gì tôi muốn làm trên sở dữ liệu MySQL của tôi .

Tôi muốn làm:

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

Nếu điều đó sẽ không quay trở lại bất kỳ hàng, mà có thể thông qua if(dr.HasRows == false), bây giờ tôi sẽ tạo ra một UPDATEtrong những purchaseOrdercơ sở dữ liệu:

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

Làm thế nào tôi có thể làm cho quá trình này ngắn hơn một chút?


4
các mục cơ sở dữ liệu được xác định có một ID duy nhất được gọi itemsOrdered_IDvà có purchaseOrder_IDcác giá trị định kỳ
John Ernest Guadalupe

1
mặt khác, purchaseordercơ sở dữ liệu có ID duy nhấtpurchaseOrder_ID
John Ernest Guadalupe

Câu trả lời:


408

Đối với truy vấn cụ thể của bạn, bạn có thể làm:

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

Tuy nhiên, tôi có thể đoán rằng bạn đang lặp ở cấp độ cao hơn. Để đặt tất cả các giá trị như vậy, hãy thử điều này:

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
Trên thực tế trong MySQL, truy vấn con tương quan phải là một trong những cách tiếp cận hiệu quả nhất, giả sử có một chỉ mục trên các mặt hàngOrdered.purchaseOrder_ID.
Gordon Linoff

8
@eggyal. . . Tôi đồng ý rằng không có chỉ mục, phiên bản tương quan có lẽ ít hiệu suất hơn so với tham gia (phụ thuộc vào nhiều yếu tố khác nhau, chẳng hạn như nhân các hàng). Tuy nhiên, với một chỉ mục, nó sẽ tốt hơn một phép nối vì nó sẽ dừng quét chỉ mục ở trận đấu đầu tiên. Kiểm tra dev.mysql.com/doc/refman/5.5/vi/ .
Gordon Linoff

53

Bạn có thể sử dụng UPDATEcú pháp nhiều bảng để tạo hiệu ứng ANTI-JOINgiữa 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

Vì MySQL không hỗ trợ if exists(*Your condition*) (*Write your query*), bạn có thể đạt được 'mệnh đề if' bằng cách viết như sau:

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

27

Bạn cũng có thể sử dụng truy vấn sau để kiểm tra xem bản ghi có tồn tại không và sau đó cập nhật nó:

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
Tôi đang vật lộn để xem làm thế nào điều này trả lời câu hỏi?
theMayer 3/03/2016

1
@theMayer Tôi cũng vậy nhưng đó là một câu trả lời khá hay
Gabriel

2
Xin chúc mừng, mã của bạn đã được chọn là một mã bị xáo trộn.
Vishwanath Dalvi

1
Tôi đoán đây là một ví dụ về những gì chúng ta có thể làm bằng cách sử dụngSQL
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
Sẽ thật tuyệt nếu bạn cũng giải thích câu trả lời, mã chỉ câu trả lời không hữu ích cho người dùng trong tương lai
Kumar Saurabh

9

sau khi máy chủ sql 2008 cung cấp Mergeđể chèn, cập nhật và xóa hoạt động dựa trên câu lệnh khớp duy nhất, cũng cho phép bạn tham gia. ví dụ mẫu dưới đây có thể giúp bạn.

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

như thế này bạn có thể chèn, cập nhật và xóa trong một câu lệnh.

và để biết thêm thông tin, bạn có thể tham khảo các tài liệu chính thức trên https://technet.microsoft.com/en-us/l Library / bb522522 ( v = sql.105) .aspx


7

Nếu bảng chứa hàng triệu bản ghi thì truy vấn sau sẽ hoạt động nhanh.

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

Bạn có thể khai báo một biến giữ số lượng kết quả trả về trên truy vấn chọn. Sau đó, bạn có thể chạy câu lệnh cập nhật nếu biến này lớn hơn 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'        
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.