메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
EXISTS는 예 또는 아니오의 질문을 합니다: 이 서브쿼리가 무언가를 찾았는가. 서브쿼리가 무엇을 반환했는지는 상관하지 않고 행이 있었는지만 보므로, 관련된 행이 있는지 검사하되 그 열은 하나도 필요 없을 때 알맞은 도구입니다. 시작하기 전에 mysql -u root -p sakila로 클라이언트를 여세요.

EXISTS의 동작 방식

COLUMN_LIST를 원하는 열로, TABLE_NAME과 OTHER_TABLE을 2개의 테이블로, OUTER_ALIAS와 INNER_ALIAS를 그 이름으로, COLUMN_NAME을 둘을 연결하는 열로, 안쪽의 WHERE를 행을 관련되게 만드는 조건으로 바꾸세요. SELECT 1은 관례입니다. select 목록은 무시되므로 SELECT 1, SELECT *, SELECT column은 똑같이 동작하고, 1은 아무것도 읽지 않는다는 것을 분명하게 말해 줍니다. 이 서브쿼리는 상관 서브쿼리입니다: 바깥 행을 참조합니다. 서버는 첫 번째로 일치하는 행에서 멈출 수 있는데, 예라고 답하기에는 1개면 충분하기 때문입니다.

예제

  1. 일치하는 것이 있는 행

6개의 언어 중 1개에 영화가 있습니다.

  1. 일치하는 것이 없는 행

NOT EXISTS가 나머지 부분이고, 안티 조인을 쓰는 방법입니다.
나머지 5개입니다. LEFT JOIN 레슨은 같은 질문에 WHERE f.film_id IS NULL로 답하고, 2가지 형태는 같은 행을 반환합니다.

NOT IN이 안전하지 않은 곳에서 NOT EXISTS는 안전합니다

IN 레슨은 목록에 NULL이 들어 있을 때 NOT IN이 행을 하나도 반환하지 않는 모습을 보여 줍니다. NOT EXISTS에는 그런 함정이 없는데, 값을 비교하지 않기 때문입니다: 행을 셉니다. 그러므로 서브쿼리가 NULL일 수 있는 열을 읽을 때는 NOT EXISTS를 쓰세요. NOT IN은 NOT NULL로 선언된 열에서는 괜찮고, 그것이 더 이상 성립하지 않는 순간 위험 요소가 됩니다.

EXISTS는 행을 절대 늘리지 않습니다

일치하는 행이 여러 개인 테이블로의 조인은 바깥 행을 일치마다 한 번씩 반복하며, INNER JOIN 레슨이 그것을 보여 줍니다. EXISTS는 그렇게 할 수 없습니다: 예 또는 아니오로 답하므로, 일치가 몇 개이든 각 바깥 행은 한 번만 나타납니다. EXISTS, IN, 조인은 모두 “관련된 행이 있다”를 표현할 수 있고, 어느 것이 가장 빠른지는 데이터에 따라 다릅니다. MySQL의 서브쿼리 대 JOIN이 플랜과 함께 그것들을 비교합니다.

요약

  • 서브쿼리가 행을 하나라도 찾는지 검사하려면 EXISTS를 사용하세요.
  • select 목록은 무시되므로, 안에는 SELECT 1을 쓰세요.
  • 일치하는 것이 없는 행에는 NOT EXISTS를 사용하세요.
  • 서브쿼리 열이 NULL일 수 있으면 NOT IN보다 NOT EXISTS를 쓰세요.
  • 조인이라면 일으켰을 행의 증가가 없다고 예상하세요.

함께 보기