Як я можу ввести рядок "if" у рядок 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
У базі даних items впорядкований унікальний ідентифікатор, що називається, itemsOrdered_IDі має повторювані purchaseOrder_IDзначення
Джон Ернест Гуадалупе

1
З purchaseorderіншого боку, в базі даних є унікальний ідентифікатор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.
Гордон Лінофф

8
@eggyal. . . Я погоджуюсь, що без індексу корельована версія, можливо, менш ефективна, ніж з'єднання (залежить від різних факторів, таких як множення рядків). З індексом, однак, він повинен бути кращим, ніж приєднання, оскільки він повинен зупинити сканування індексу під час першого матчу. Перевірте dev.mysql.com/doc/refman/5.5/en / ... .
Гордон Лінофф

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
буде чудово, якщо ви також поясніть відповідь, лише відповіді на код не допоможуть майбутнім користувачам
Kumar Saurabh

9

після sql-сервера 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'        
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.