SQL 문자열에 'if 절'을 어떻게 넣습니까?


190

MySQL 데이터베이스 에서 수행하려는 작업은 다음과 같습니다 .

나는하고 싶다 :

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

즉 통해 가능한 모든 행을 반환하지 않을 경우 if(dr.HasRows == false), 나는 지금 만들 것 UPDATEpurchaseOrder데이터베이스를 :

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사이에 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

MySQL은을 지원하지 않으므로 if exists(*Your condition*) (*Write your query*)다음과 같이 작성하여 'if 절'을 달성 할 수 있습니다.

(*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 나도 그래도 꽤 좋은 답변입니다
Gabriel

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보다 큰 경우 update 문을 실행할 수 있습니다

    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.