본문 바로가기

데이터베이스/SQL

09. SQL문 속 또 다른 SQL문, 서브쿼리(P.242~)

09-1. 서브쿼리란?

: 서브쿼리(Subquery)는 SQL문을 실행하는데 필요한 데이터를 추가로 조회하기 위해 SQL문 내부에서 사용하는 SELECT문을 의미한다.

 

1) 문법

2) 예시/결과 : EMP 테이블에서 JONES보다 급여가 높은 사원을 조회한다면?

 

- 예시

SELECT * FROM EMP
WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME='JONES');

- 결과

 

3) 실무활용

 

- 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 개수로 지정해야 한다. 즉, 메인쿼리의 비교 대상 데이터가 하나라면 서브쿼리의 SELECT절 역시 같은 자료형인 열을 하나 지정해야 합니다.(* P258. 09-4. 다중열 서브쿼리)

- 서브쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류와 호환 가능해야 한다. 즉, 메인쿼리에 사용한 연산자가 단 하나의 데이터로만 연산이 가능한 연산자라면 서브쿼리의 결과 행 수는 반드시 하나여야 한다. 이 내용은 '단일행 서브쿼리 및 다중행 서브쿼리'에서 자세히 살펴본다.

(* P246. 09-2. 단일행 서브쿼리 / 09-3. 다중행 서브쿼리) 

 

09-2. 실행 결과가 하나인 단일행 서브쿼리

: 단일행 서브쿼리(single-row subquery)는 실행 결과가 단 하나의 행으로 나오는 서브쿼리를 뜻한다. 

1) 문법 : 서브쿼리에서 출력되는 결과가 하나 이므로, '단일행 연산자'를 사용하여 비교한다.

단 일 행      연 산 자
> >= = <= < <> ^= !=
초과 이상 같음 이하 미만 같지 않음

2) 예시/결과

 

- 예시 : EMP 테이블에서 SCOTT보다 빨리 입사한 사원 목록 조회

- 결과 

- 예시 : EMP 테이블에서 20번 부서에 속한 사원 중 전체 사원의 평균 급여보다 높은 급여를 받는 사원 정보와 소속 부서 정보를 조회하라.

SELECT *
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO 
AND E.DEPTNO=20
AND E.SAL > (SELECT AVG(SAL) FROM EMP);

-결과 

09-3 실행 결과가 여러 개인 다중행 서브쿼리

: 다중행 서브쿼리(multiple-row subquery)는 실행 결과가 여러 개의 행으로 나오는 서브쿼리를 뜻한다. 

1) 문법 : 서브쿼리에서 출력되는 결과가 여러 개 이므로, '다중행 연산자'를 사용하여 비교한다.

다중행 연산자 설명
IN 메인쿼리의 데이터가 서브쿼리의 결과 중 하나라도 일치한 데이터가 있다면 TRUE // 하나라도
ANY, SOME 메인쿼리의 조건식을 만족하는 서브쿼리의 결과가 하나 이상이면 TRUE // 하나 이상이면
ALL 메인쿼리의 조건식을 서브쿼리의 결과 모두가 만족하면 TRUE // 모두 만족
EXISTS 서브쿼리의 결과가 존재하면(즉, 행이 1개 이상일 경우) TRUE // 서브쿼리 결과 있는 경우

2)  예시/결과

 

2-1) ANY/SOME 연산자

 : 서브쿼리가 변환한 여러 결과 값 중 메인쿼리와 조건식을 사용한 결과가 하나라도 TRUE 이면, 메인 쿼리 조건식을 TRUE로 반환 해 준다.

 

#참고자료1. ANY/SOME 연산자

- 예시

/*메인쿼리-서브쿼리*/
SELECT *
FROM EMP
WHERE SAL < ANY(SELECT SAL
                  FROM EMP
                  WHERE DEPTNO = 30)
ORDER BY SAL, EMPNO;                  

/*서브쿼리*/
SELECT SAL
FROM EMP
WHERE DEPTNO = 30;

/*서브쿼리 없는 메인쿼리*/
SELECT SAL
FROM EMP
ORDER BY SAL, EMPNO; 

- 결과

#1. 메인쿼리+서브쿼리 결과 값 (실습9-11)

: 사실 상, 서브쿼리의 '2850' 보다 작은 수가 출력된다.

#2. 서브쿼리

#3. 서브쿼리 없는 메인쿼리 

2-2) ALL 연산자

: ALL 연산자는 서브쿼리의 모든 결과가 조건식에 맞아떨어져야만 메인쿼리의 조건식이 TRUE가 되는 연산자입니다.

 

# 참고자료 1. ALL 연산자 

- 예시 

/*메인쿼리-서브쿼리*/
SELECT *
FROM EMP
WHERE SAL < ALL (SELECT SAL
                 FROM  EMP
                 WHERE DEPTNO = 30);
/*서브쿼리*/
SELECT SAL
FROM  EMP
WHERE DEPTNO = 30;

/*서브쿼리 없는 메인쿼리*/
SELECT SAL
FROM EMP;

 

- 결과

#1. 메인쿼리 + 서브쿼리 (실습9-14)

#2. 서브쿼리

#3. 서브쿼리 없는 메인쿼리