데이터베이스 기초
고객 표(고객ID, 이름)와 주문 표(주문ID, 고객ID, 금액)에서 한 번도 주문하지 않은 고객의 이름을 구하려고 한다. 올바른 SQL 문은?
- ASELECT 이름 FROM 고객 WHERE EXISTS (SELECT * FROM 주문 WHERE 주문.고객ID = 고객.고객ID)
- BSELECT 이름 FROM 고객 WHERE NOT EXISTS (SELECT * FROM 주문)
- CSELECT 이름 FROM 고객 WHERE NOT EXISTS (SELECT * FROM 주문 WHERE 주문.고객ID = 고객.고객ID)
정답과 해설 보기
정답: C. SELECT 이름 FROM 고객 WHERE NOT EXISTS (SELECT * FROM 주문 WHERE 주문.고객ID = 고객.고객ID)
EXISTS는 괄호 안의 부질의가 한 행이라도 결과를 반환하면 참, 한 행도 반환하지 않으면 거짓이 되는 술어이며, NOT EXISTS는 그 반대입니다. 부질의 안에서 주문.고객ID = 고객.고객ID처럼 바깥 표의 열을 사용하면, 바깥 고객 표의 한 행마다 그 고객의 주문이 있는지를 조사하는 상관 부질의가 됩니다. 이를 NOT EXISTS와 조합하면 주문이 한 건도 없는 고객만 남습니다. EXISTS로 하면 반대로 주문한 적이 있는 고객이 구해집니다. 부질의에 고객과 대응시키는 조건이 없으면, 주문 표에 한 행이라도 있으면 부질의는 항상 행을 반환하므로 NOT EXISTS는 항상 거짓이 되어 결과는 0행이 됩니다. 같은 결과는 LEFT OUTER JOIN으로 조인하여 주문 쪽 열이 NULL이 되는 행을 고르는 방법으로도 얻을 수 있습니다.