Database/SQL

Subquery 서브쿼리사용법, ALL, ANY, IN, EXISTS

리커니 2013. 5. 23.
반응형

 

Subquery 서브쿼리사용법, ALL, ANY, IN, EXISTS

 

* 서브쿼리의 사용.

서브쿼리란?

서브쿼리는 SELECT문 내의 또다른 SELECT문이라고 생각하시면 됩니다.

서브쿼리는 왜 사용하나?

기본적인 SELECT문의 데이터 외에 데이터를 가공하여 사용할 필요가 있을 때 사용합니다.

서브쿼리는 어디어디에서 사용할 수 있나?

서브쿼리는 SELECT, INSERT, UPDATE, DELETE 어디에서 사용 가능하고, SELECT리스트, FROM절, WHERE절에서도 사용이 가능합니다.

서브쿼리의 사용법

서브쿼리는 (SELECT...)로 사용합니다.  반드시 괄호 사용!

 

 

 

*예제

아래와 같은 AMT_MST_TEST 테이블이 있습니다.

1. 서브쿼리의 사용 - SELECT리스트

'이순신' 의 데이터를 가져오되 그 부서의 평균 연봉을 가져오라.

 

SELECT T1.*
           , (SELECT AVG(SALARY)
                FROM AMT_MST_TEST S1
               WHERE S1.DEPT_CD = T1.DEPT_CD) AS AVG_SALARY
  FROM AMT_MST_TEST T1
 WHERE T1.EMP_NM = '이순신'

 

서브쿼리를 사용하여 이순신의 부서와 같은 부서의 평균연봉을 가져왔고 AVG_SALARY 라는 별칭을 주었습니다.

 

2. 서브쿼리의 사용 - FROM절

부서코드가 '1D014' 인 사원들의 이름, 성별, 입사일자를 서브쿼리를 사용하여 가져오라.

 

SELECT T1.EMP_NM
     , T1.GEN_DIV
     , T1.JOIN_DT
  FROM (SELECT * 
          FROM AMT_MST_TEST S1
         WHERE S1.DEPT_CD = '1D014') T1

 

테이블이 들어갈 FROM절에 서브쿼리를 사용하였습니다. 서브쿼리 대신 AMT_MST_TEST 를 쓰고 WHERE절을 써도 됩니다.

 

3. 서브쿼리의 사용 - WHERE절

'이순신'과 같은 부서에 있는 사람을 가져오되 '이순신'은 제외하고 가져오라.

 

SELECT *
  FROM AMT_MST_TEST T1
 WHERE T1.DEPT_CD = (SELECT S1.DEPT_CD
                       FROM AMT_MST_TEST S1
                      WHERE S1.EMP_NM = '이순신')
   AND T1.EMP_NM <> '이순신'  
--   AND T1.EMP_NM NOT LIKE '이순신'  -- 위의 AND절과 같은 결과.

 

WHERE절에 서브쿼리를 사용하여 '이순신'과 같은 부서를 SELECT 하였습니다.

 

4. 서브쿼리의 사용 - ALL, ANY

'마케팅 부서'에 있는 사원들의 연봉보다 많은 연봉을 받는 사람보다 많은 월급을 받는 사람 출력

 

SELECT *
  FROM AMT_MST_TEST T1
 WHERE T1.SALARY > ALL(SELECT S1.SALARY
                         FROM AMT_MST_TEST S1
                         LEFT JOIN DEPT_MST_TEST S2 ON (S2.DEPT_CD = S1.DEPT_CD)
                        WHERE S2.DEPT_NM_KOR = '마케팅부서')

 

서브쿼리문 앞에 ALL을 사용하게 되면 서브쿼리에서 조회되는 결과중 전부 일치하는 데이터만 출력하게 됩니다. 위의 서브쿼리를 조회하면 1800만원, 2200만원, 3000만원을 조회하게 되는데 전부 일치하는 조건이니 1800 AND 2200 AND 3000보다큰 데이터를 조회하게 됩니다. 이처럼 ALL은 조회하는 데이터에 AND 조건을 건다고 생각하시면 됩니다. 그러니 3000만원 보다 많이 받는 '유관순'만 조회하게 되는 것이죠.

 

SELECT *
   FROM AMT_MST_TEST T1
  WHERE T1.SALARY > ANY(SELECT S1.SALARY
                          FROM AMT_MST_TEST S1
                          LEFT JOIN DEPT_MST_TEST S2 ON (S2.DEPT_CD = S1.DEPT_CD)
                         WHERE S2.DEPT_NM_KOR = '마케팅부서')

 

 

서브쿼리문 앞에 ANY을 사용하게 되면 서브쿼리에서 조회되는 결과중 하나라도 일치하는 데이터를 출력하게 됩니다. 위의 서브쿼리를 조회하면 1800만원, 2200만원, 3000만원을 조회하게 되는데 하나라도 일치한다면 하는 조건이니 1800 OR 2200 OR 3000보다큰 데이터를 조회하게 됩니다. 이처럼 ANY는 조회하는 데이터에 OR 조건을 건다고 생각하시면 됩니다. 그러니 1800만원 보다 많이 받는 사람들의 데이터를 조회하게 되는 것이죠.

 

 5. 서브쿼리의 사용 IN, EXISTS

알맞는 SELECT문은 아니지만 위의 쿼리를 사용하여 예를 들도록 하겠습니다.

 

SELECT *
   FROM AMT_MST_TEST T1
  WHERE T1.SALARY IN (SELECT S1.SALARY
                        FROM AMT_MST_TEST S1
                        LEFT JOIN DEPT_MST_TEST S2 ON (S2.DEPT_CD = S1.DEPT_CD)
                       WHERE S2.DEPT_NM_KOR = '마케팅부서')

 

IN의 부정은 NOT IN 을 사용합니다. NOT IN을 사용하면 서브쿼리의 결과 값과 같지 않은 데이터가 출력되겠죠.

 

 

위에서 보신바와 같이 서브쿼리의 결과값은 1800, 2200, 3000만원 이었습니다. 여기에 IN을 사용하게 되면 서브쿼리의 결과 값과 같은 값을 갖는 모든 데이터를 조회하게 됩니다. 같은 항목이 한개인 것만 조회를 할 경우에는 '='을 사용하고 여러개일 경우에는 'IN'을 사용하게 되는 것이죠.

 

SELECT *
  FROM AMT_MST_TEST T1
 WHERE EXISTS (SELECT S1.SALARY
                 FROM AMT_MST_TEST S1
                 LEFT JOIN DEPT_MST_TEST S2 ON (S2.DEPT_CD = S1.DEPT_CD)
                WHERE S2.DEPT_NM_KOR = '마케팅부서')

 

EXISTS의 의미는 '존재하다' 입니다. 즉 WHERE문에서 존재하면 '참', 존재하지 않는다면 '거짓'이 되죠. EXISTS의 부정은 NOT EXISTS 을 사용합니다. NOT EXISTS을 사용하면 서브쿼리의 결과값이 존재하지 않는경우 출력을 하지 않고, 존재한다면 출력을 합니다.

 

 

위에서 본것과 같이 서브쿼리의 데이터가 있으니 모든 데이터가 출력이 됩니다.

서브쿼리는 사용빈도가 높으니 확실하게 습득하도록 합니다.

 

반응형

댓글

💲 추천 글