ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL - IN, EXITS, ANY, ALL
    SQL 2022. 12. 10. 16:05

    *IN

    ‘=’비교만 가능하고, OR 조건 검색 결과를 가져온다.

    서브쿼리가 먼저 실행되고 그 결과를 바탕으로 메인쿼리가 실행된다.

     

    *EXISTS

    메인쿼리의 비교 조건이 서브쿼리의 결과 중에 만족하는 값이 있다면 1, 없다면 0

    메인쿼리를 먼저 실행한다 -> 메인쿼리로 범위를 좁히고 서브쿼리로 값을 찾는다.

    공통된 컬럼이 없는 경우 exists하면 10에 따라 값을 다 보여주거나 다 보여주지 않는다.

    등가조인을 사용할 경우(공통된 컬럼이 있을 경우)에는 exists 비교를 통해 조건에 맞는 데이터면 1이어서 보여주고, 조건을 만족하지 않으면 0이기 때문에 보여주지 않는다.

    existsin보다 성능이 더 좋다 -> 메인쿼리로 범위를 좁혀놓고 시작하기 때문에

     

    *ANY

    메인쿼리와 비교조건이 서브쿼리 결과 중 하나라도 일치하면 참이다.

    1) = any : in과 같은 효과

    2) > any : 최솟값보다 더 크면

    3) < any : 최댓값보다 더 작으면

     

    *ALL

    ANY와 반대 개념

    1) = all : any와 같지만 or이 아니라 and 연산이다. -> 값이 하나인 것과 값이 여러 개 인 것을 비교하는 것 자체가 잘못되었으므로 무조건 값이 하나가 나오는 쿼리여야 한다.

    2) < all : 최솟값보다 더 작으면

    3) > all : 최댓값보다 더 크면

     

    => ANYALLMAX, MIN과 성능 차이가 없기 때문에 아무거나 사용해도 된다.

     

    -- 1. IN : = 비교만 가능, OR 조건 검색 결과 내용을 가져온다.
    -- 서브쿼리가 먼저 실행되고, 그 결과를 바탕으로 메인쿼리가 동작한다.
    select ename, job from emp where deptno in (2,4);
    select ename, job from emp where deptno in (select deptno from dept where loc in ('la','boston'));
    
    -- 2. EXISTS : 메인 쿼리의 비교 조건이 서브쿼리의 결과 중에 만족하는 값이 하나라도 존재하면 1 혹은 0 반환
    -- 메인쿼리로 범위를 좁히고 서브쿼리로 값을 찾는다.
    -- exists는 결과값이 있으면 1, 없으면 0을 반환
    select exists (select deptno from dept where loc in ('la','boston')) as bool;
    
    select ename, job, deptno from emp where exists (select deptno from dept where loc in ('la','boston'));
    select ename, job, deptno from emp where 1;
    
    select ename, job, deptno from emp where exists (select deptno from dept where loc in ('korea'));
    select ename, job, deptno from emp where 0;
    
    -- 그럼 어떻게 사용하는가?
    -- 1) 메인쿼리가 실행된다.
    select ename, job, deptno from emp;
    -- 2) 이 메인쿼리 내용을 서브쿼리에서 걸러준다. (등가조인처럼 양쪽 테이블에 모두 있는 내용을 가져온다.) -> 0이면 값을 안 보여주기 때문에
    select ename, job, deptno from emp e where exists (select deptno from dept d where e.deptno = d.deptno);
    -- 결과적으로 왜 이렇게 나오나?
    -- 공통되는 컬럼이 있을 경우 행마다의 exists 비교를 통해 보여주고 안 보여주고 하는 것이다. -> emp의 deptno와 dept의 deptno가 같은지 계속 비교를 하기 때문에
    
    -- in 과의 사용법 비교
    select ename, job from emp where deptno in (select deptno from dept where loc in ('la','boston'));
    
    select ename, job from emp e where exists(select deptno from dept d where d.deptno = e.deptno and (d.loc in ('la','boston')));
    -- exists는 in보다 사용이 복잡하지만 성능이 더 좋다.
    -- in은 서브쿼리를 통해 조건을 추출하고 메인쿼리의 내용을 검색한다.
    -- exists는 메인쿼리를 통해 데이터를 확정하고 그 안에서 서브쿼리 조건을 걸러낸다.
    -- 단, exists는 메인쿼리에서 얼마나 데이터를 좁혀놓고 시작하는지가 관건이다.
    
    -- 3. ANY : 메인쿼리와 비교조건이 서브쿼리 결과 중에 하나라도 일치하면 참이다.
    -- 1) = ANY : IN과 같은 효과
    select ename, job from emp where deptno in (select deptno from dept where loc in ('la','boston'));
    
    select ename, job from emp where deptno = any (select deptno from dept where loc in ('la','boston'));
     
    -- 2) > ANY : 최소값보다 크면
    -- 직책이 manager인 직원(입사일이 가장 빠른)의 입사일보다 늦은 직원의 이름과 직책과 입사일
    -- 1. 직책이 manager인 입사일이 가장 빠른 직원
    select MIN(hiredate) from emp where job = 'manager';
    -- 2. 입사일이 2015-08-12 보다 늦은 직원 찾기
    select ename, job, hiredate from emp where hiredate > '2015-08-12';
    
    select ename, job, hiredate from emp where hiredate > (select MIN(hiredate) from emp where job = 'manager');
    
    select ename, job, hiredate from emp where hiredate > any (select hiredate from emp where job = 'manager');
    
    -- 3) < ANY : 최대값보다 작으면
    -- 직책이 manager인 직원(입사일이 가장 늦은)의 입사일보다 빠른 직원의 이름과 직책과 입사일
    select ename, job, hiredate from emp where hiredate < (select MAX(hiredate) from emp where job = 'manager');
    
    select ename, job, hiredate from emp where hiredate < any (select hiredate from emp where job = 'manager');
    
    -- 4. ALL : ANY와 반대 개념
    -- 1) = ALL : ANY와 같지만 OR 조건이 아닌 AND 조건이다.
    select ename, job from emp where deptno = all(select deptno from dept where loc = 'newyork');
    
    select deptno from dept where loc = 'newyork'; -- 1,3
    -- = all 안의 조건은 and 이므로 deptno=1 AND deptno=3 이므로 맞는 조건이 없다.
    -- 그래서 결과값이 하나만 나오는 조건으로 사용해야 한다.
    select ename, job from emp where deptno = all(select deptno from dept where loc = 'newyork' and deptname = 'sales');
    
    -- 2) > ALL : 최대값보다 크면
    select ename, job, hiredate from emp where hiredate > (select MAX(hiredate) from emp where job = 'manager');
    
    select ename, job, hiredate from emp where hiredate > all (select hiredate from emp where job = 'manager');
    
    -- 3) < ALL : 최소값보다 작으면
    select ename, job, hiredate from emp where hiredate < (select MIN(hiredate) from emp where job = 'manager');
    
    select ename, job, hiredate from emp where hiredate < all (select hiredate from emp where job = 'manager');

    'SQL' 카테고리의 다른 글

    SQL - VIEW  (0) 2022.12.10
    SQL - INDEX  (0) 2022.12.10
    SQL - SET  (0) 2022.12.10
    SQL - JOIN  (1) 2022.12.10
    SQL - 서브쿼리  (0) 2022.12.10
Designed by Tistory.