SQL 기초 (5) - 서브쿼리

Ek_5.4·2020년 7월 13일
0

SQL 실습

목록 보기
5/8

서브쿼리

: 메인쿼리 안에 있는 또 다른 SELECT 문장
※ 서브쿼리를 구성하는 SELECT 문장은 항상 괄호로 둘러싸여 있음.

(1) SELECT 절에 사용되어 특정 값을 반환할 수 있다.
(2) FROM 절에 사용되어 마치 테이블처럼 사용할 수 있다.
(3) WHERE 절에 사용되어 조건 값을 비교할 때 사용할 수 있다.

  • 스칼라 서브쿼리
    : 메인쿼리의 SELECT 절에서 컬럼이나 표현식처럼 사용.
    단 하나의 컬럼이나 표현식만 사용할 수 있음.
SELECT a.emp_id
      ,a.emp_name
      ,a.gender
      ,a.age
      ,a.dept_id
      ,( SELECT b.dept_name
           FROM dept_master b
          WHERE a.dept_id = b.dept_id ) dept_name
FROM emp_master a
ORDER BY 1;

  • 인라인 뷰
    : 메인쿼리의 FROM 절에서 사용하는 서브쿼리.
    서브쿼리 자체가 하나의 테이블로 사용.
    여러개의 컬럼, 여러개의 로우로 반환 가능.
SELECT a.dept_id
      ,a.dept_name
      ,k.emp_id
      ,k.emp_name
      ,k.address 
 FROM dept_master a
      ,( SELECT b.emp_id
               ,b.emp_name
               ,c.city || c.gu || c.address_name AS address
               ,b.dept_id
          FROM  emp_master b
               ,address_master c
         WHERE  b.address_id = c.address_id
       ) k
WHERE a.use_yn  = 'Y'
  AND a.dept_id = k.dept_id
ORDER BY 1, 3;

  • 중첩 서브쿼리
    : WHERE 절에서 조건절의 일부로 사용, 즉 메인쿼리 테이블의 특정 컬럼 값과 비교한 값을 반환하는 용도. 따라서 인라인 뷰처럼 여러개의 컬럼, 여러개의 로우로 반환 가능.
단일 행을 반환하는 서브쿼리
SELECT *
FROM dept_master a      
WHERE a.dept_id = (SELECT b.dept_id
                   FROM emp_master b
                   WHERE b.emp_name = '세종대왕');

다중 행을 반환하는 서브쿼리
SELECT *
FROM dept_master a
WHERE a.dept_id IN (SELECT b.dept_id
                    FROM emp_master b
                    WHERE b.age BETWEEN 40 AND 49);

다중 컬럼, 다중 행을 반환하는 서브쿼리
SELECT *
FROM emp_master a
WHERE (a.gender, a.age) 
   IN (SELECT b.gender, b.age
         FROM emp_master b,
              address_master c
        WHERE b.address_id = c.address_id
          AND c.gu IN ('중구', '서대문구'));

  • 세미조인(EXISTS)과 안티조인(NOT, NOT EXISTS)

(1) EXISTS 연산자를 사용한 세미조인

중첩 서브쿼리에서 사용한 조인방법. 
EXISTS 연산자는 메인쿼리의 케이블 데이터를 기준으로 
서브쿼리에서 반환하는 데이터가 존재하면 참(TRUE)을 반환.
SELECT *
  FROM dept_master a      
 WHERE EXISTS (SELECT 1
                 FROM emp_master b
                WHERE b.age BETWEEN 40 AND 49
                  AND a.dept_id = b.dept_id);

(2) NOT 연산자을 사용한 안티조인

SELECT *
  FROM dept_master a      
 WHERE a.dept_id NOT IN (SELECT b.dept_id
                           FROM emp_master b
                          WHERE b.age BETWEEN 40 AND 49);

  1. NOT EXISTS 연산자를 사용한 안티조인
SELECT *
  FROM dept_master a      
 WHERE NOT EXISTS (SELECT 1
                    FROM emp_master b
                    WHERE b.age BETWEEN 40 AND 49
                    AND a.dept_id = b.dept_id);

profile
Data analysis beginner

1개의 댓글

comment-user-thumbnail
2021년 4월 4일

감사합니다!

답글 달기