프로그래밍/Oracle

[Oracle] 단일행/다중행 서브 쿼리

eunki 2022. 6. 2. 01:22
728x90

서브 쿼리의 종류

  1. 단일행 서브쿼리 (single row subquery) : 서브 쿼리에서 메인 쿼리로 하나의 값이 리턴되는 경우
    사용할 수 있는 연산자: =, !=, ^=, 〉, 〈, 〉=, 〈=
  2. 다중행 서브쿼리 (multiple row subquery) : 서브 쿼리에서 메인 쿼리로 여러 개의 값이 리턴되는 경우
    사용할 수 있는 연산자: in, not in, >all, <all, >any, <any
  3. 다중 컬럼 서브쿼리 (multiple column subquery) : 서브 쿼리에서 메인 쿼리로 여러 개의 컬럼 값이 리턴되는 경우
    사용할 수 있는 연산자: in, not in

 

 

 

 

예제 1. JONES 의 월급보다 더 많은 월급을 받는 사원들의 이름과 월급을 출력

select ename, sal
    from emp
    where sal > (select sal
                    from emp
                    where ename = 'JONES');

괄호 안에 해당하는 부분이 서브 쿼리이고, 나머지 부분은 전부 메인 쿼리다.

 

 

 

예제 2. 직업이 SALESMAN 인 사원들과 같은 월급을 받는 사원들의 이름과 월급을 출력

select ename, sal
    from emp
    where sal = (select sal
                    from emp
                    where job = 'SALESMAN');

위와 같이 수행하면 에러가 발생하는 이유는 서브 쿼리에서 메인 쿼리로 여러 개의 값이 리턴 되기 때문이다.

직업이 SALESMAN 인 사원들의 월급이 여러 개 이므로 이퀄(=)로 비교 할 수는 없고 in 으로 비교해야 한다.

 

 

select ename, sal
    from emp
    where sal in (select sal
                    from emp
                    where job = 'SALESMAN');

위와 같이 서브 쿼리에서 메인 쿼리로 여러 개의 값이 리턴 되는 경우의 서브 쿼리 문법을 다중행 서브쿼리 (multiple row subquery) 라고 한다.

 

 

 

 예제 3. 직속 상사(관리자)가 아닌 사원들의 이름을 출력

select ename
    from emp
    where empno not in (select mgr
                          from emp);

위와 같이 SQL을 작성하면 선택된 레코드가 없다고 나온다.

그 이유는 서브 쿼리에서 메인 쿼리로 값이 리턴 될 때, NULL 값이 리턴되기 때문이다.

 

 

select ename
    from emp
    where empno not in (select mgr
                          from emp
                          where mgr is not null);
select ename
    from emp
    where empno not in (select nvl(mgr, -1)
                          from emp);

null 값만 리턴 되지 않도록 해준다.

null 은 알 수 없는 값이므로 = 또는 ^= 로는 비교할 수 없다.

null 값을 검색하기 위한 기타 비교 연산자인 is null 이나 is not null 로 검색해야 한다.

 

 

 

예제 4. 직업이 SALESMAN 인 사원들 중에서 최대 월급보다 더 많은 월급을 받는 사원들의 이름과 월급을 출력

select ename, sal
    from emp
    where sal >all (select sal
                        from emp
                        where job = 'SALESMAN');

>all 은 이 모든 값보다 크다 라는 뜻이다.

 

 

 

예제 5. 직업이 SALESMAN 인 사원들의 월급 중에서 최소 월급보다 더 많은 월급을 받는 사원들의 이름과 월급을 출력

select ename, sal
    from emp
    where sal >any (select sal
                        from emp
                        where job = 'SALESMAN');

>any 는 이 어느 것보다 크기만 하면 된다 라는 뜻이다.

728x90