인프런 커뮤니티 질문&답변

hunter님의 프로필 이미지

작성한 질문수

데이터 분석 SQL Fundamentals

exists 와 in 차이

24.09.11 21:46 작성

·

54

0

안녕하세요,

Where절 서브쿼리 사용 시 유의사항 part 듣다가 질문드립니다

 

앞전에 exists 사용법에 대해 나오지 않아서 이 파트 들으면서 처음 봤는데요!

비상관 서브 쿼리 - in 을 사용해서 설명

상관 서브쿼리 exists 를 사용해서 설명

해주셨는데

 

in을 사용한 비상관 서브쿼리에서도 상관서브쿼리처럼 메인쿼리의 연결 컬럼을 넣어줘도 작동이되어서요

그럼 비상관 서브쿼리랑 상관 서브쿼리랑 차이가 없는것처럼 보여서 헷갈립니다 ㅠ

 

그리고 언제 in 을 사용한 서브쿼리를 활용하는지, exists 를 사용하는지 궁금합니다

from ( 서브쿼리 ) 이렇게 해줘도 될것같은데 어떤 차이인지 해서요!

답변 2

0

권 철민님의 프로필 이미지
권 철민
지식공유자

2024. 09. 12. 15:27

안녕하십니까,

서브쿼리 강의를 좀 더 들으시면 질문에 대한 이해가 좀 더 도움이 되시겠지만,

우선,

in은 상관/비상관 관계없이 다 사용 가능합니다. exists는 상관 서브쿼리로만 동작합니다.

서브 쿼리를 처음 배울 때 상관/비상관 여부는 기능적인 여부를 떠나서 왜 이게 필요한지에 대한 근본적인 질문이 더 중요할 수 있습니다(아마 질문하신 맥락도 이 부분이 더 중점인것 같습니다)

개인적인 생각으로 서브쿼리를 상관/비상관 방식으로 나누는 것 보다는 서브쿼리에서 만들어진 집합을 메인 쿼리로 전달하는가, 아님 메인 쿼리의 조건을 서브 쿼리에 따라서 CHECK 하여 필터링 하는가를 구분하는게 더 중요하다고 생각합니다. 하지만 후자로 구분하는 것은 SQL 경력이 그렇게 많지 않다면, 오히려 헷갈리기 쉽습니다. 그래서 좀 더 기계적으로 서브쿼리를 상관/비상관 방식으로 분류합니다.

가능하면 IN은 상관 방식으로 사용하는 것이 좋습니다. 그래야 Exists와 구분이 되기 때문입니다.

(그렇게 되지 않는 경우도 있지만) 일반적으로 상관 방식은 서브쿼리 내에서 집합을 만들어서 메인 쿼리로 전달하는 방식으로 SQL의 실행 계획이 만들어집니다. 즉 연결을 시작하는 주체가 서브쿼리가 됩니다.

(그렇게 되지 않는 경우도 있지만) 일반적으로 비상관 방식은 메인쿼리 집합의 레코드를 하나씩 서브쿼리로 연결해서 메인쿼리 집합의 레코드를 필터링 체크합니다. 둘 다 연결을 하지만, 연결 시작의 주체가 누가 되느냐가 차이가 있습니다. 그리고 DBMS 내에서 수행 속도를 최적으로 하기 위해서 상관, 비상관에 최적인 실행 계획이 만들어 지게 됩니다.

IN, Exists 키워드 모두 적용 결과가 동일하지만, SQL 문맥적으로 약간의 차이가 있습니다. Exists라는 키워드는 '존재 하는가' 측면에서 필터링 체크를 하는 것입니다. 즉 메인 쿼리의 레코드들이 서브쿼리 집합과 연결되어서 존재하는가 를 체크하는 키워드 입니다.

exists의 물리적인 키워드는 이런 의미이고, 이게 업무에서는 아래와 같은 메인 테이블의 필터링 조건을 타 테이블에서 찾아볼 때 주로 사용됩니다.

주문 테이블(orders)에서 상품 금액(order_items 의 amount 컬럼) 이 100보다 큰 주문을 한 주문 정보를 알고 싶다.

select * from nw.orders a where exists (select order_id from nw.order_items x where a.order_id = x.order_id and x.amount > 100);

위 쿼리의 서브쿼리 절의 select order_id 는 select 1 로 해도 됩니다. order_id 값을 반환하는 것이 목적이 아니라 조건을 만족하는 지 check만 해도 되기 때문입니다.

물론 위 조건은 상관 서브쿼리로 아래와 같이 사용될 수 있습니다. 문맥적인 의미로는 주문 상품 금액이 100보다 큰 주문에 대해서 주문 정보를 알고 싶다가 될 수 있습니다.

select * from nw.orders a where order_id in (select order_id from nw.order_items where amount > 100);

 

in을 쓰느냐, exists를 쓰느냐의 기준은 어느정도 SQL 더 많이 사용하면서 체득되어야 할 부분이지만,

나름의 기준을 설정하자면

첫째로 문맥적으로 메인 쿼리의 레코드를 서브쿼리와 연결된 조건으로 필터링 하는 문맥으로 사용할 것인가(exists), 아님 서브쿼리에서 주어지는 조건에 따라서 메인쿼리로 연결할 것인가(in)로 구분할 수 있습니다.

두번째로는 답변 초반부에 언급드렸던 대로, 연결을 위한 SQL의 실행 계획 최적화를 위해서 IN, Exists가 구분되어 있습니다.

 

감사합니다.

 

0

인프런 AI 인턴님의 프로필 이미지

2024. 09. 11. 21:51

안녕하세요, 인프런 AI 인턴입니다.

hunter님께서 질문해주신 내용에 대해 유사한 질문과 답변을 찾아보았습니다. 기존의 질문과 답변을 조금 더 이해하기 쉽게 요약하였으며, 관련 URL도 함께 안내드리겠습니다.

질문 요약

  1. 비상관 서브쿼리와 상관 서브쿼리의 차이
  2. INEXISTS의 사용 시점 및 차이
  3. FROM 절 안에서 서브쿼리 사용

관련 질문 및 답변

  1. exists 사용 쿼리 질문드립니다.

    • 요약: 서브쿼리와 조인은 테이블 간의 연결 방식을 다릅니다. EXISTS는 메인 쿼리의 집합 레벨을 변경시키지 않고, 연관된 데이터를 필터링합니다. 반면 조인은 집합 레벨이 변할 수 있습니다.
  2. 상관쿼리와 비상관쿼리의 쓰임새가 헷깔립니다.

    • 요약: INEXISTS는 사용 용도가 다릅니다. IN은 서브쿼리의 결과를 메인 쿼리가 사용하며, EXISTS는 메인 쿼리가 서브쿼리의 존재 여부를 확인하는 용도로 사용됩니다. 옵티마이저가 서로 다른 실행 계획을 만들 수 있습니다.
  3. 다중행 서브쿼리에서 in과 exists 차이

    • 요약: EXISTS는 상관 서브쿼리에서 사용되며, 주로 메인 쿼리의 조건을 서브쿼리가 충족시키는지 여부를 확인합니다. 반면, IN은 서브쿼리의 결과를 메인 쿼리가 필터링하는 용도로 사용됩니다. 업무에 따라 구분 없이 사용할 수도 있지만, 상황에 맞게 사용하는 것이 좋습니다.

풍부한 설명

서브쿼리에는 상관 서브쿼리와 비상관 서브쿼리가 있습니다. 상관 서브쿼리는 메인 쿼리의 값을 서브쿼리에서 사용하여 동적 필터링을 하는 반면, 비상관 서브쿼리는 메인 쿼리와 독립적으로 동작합니다.

  • EXISTS와 상관 서브쿼리: 서브쿼리에서 메인 쿼리의 값을 사용하여 존재 여부를 확인합니다.
  • IN과 비상관 서브쿼리: 서브쿼리의 결과를 집합으로 보고, 메인 쿼리가 이 집합에 포함되는지를 확인합니다.

FROM 절에서 서브쿼리를 사용하는 경우는 기존의 테이블이 아닌, 서브쿼리의 결과를 임시 테이블처럼 사용하여 추가적인 계산이나 필터링을 할 때 유용합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

hunter님의 프로필 이미지
hunter
질문자

2024. 09. 11. 22:26

exists 를 사용할때 서브쿼리에서 메인쿼리의 값을 사용해서 존재 여부를 확인하는 이유가 뭐에요?!

in처럼 필터링을 하는 것도 아니고 메인쿼리의 집합 레벨도 변경시키지 않는데 (마치 조회하는 것처럼 생각됩니다) 어떤 조건에서 왜 필요한지 궁금합니다

hunter님의 프로필 이미지

작성한 질문수

질문하기