본문으로 건너뛰기

10장_서브쿼리

스칼라 서브쿼리

  • 메인쿼리의 SELECT 절에서 마치 컬럼이나 표현식처럼 사용
  • 스칼라 서브쿼리 내의 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;

인라인 뷰

  • 메인 쿼리의 FROM 절에 사용
  • 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 ('중구', '서대문구')
);

세미 조인과 안티 조인

세미조인

  • 메인쿼리에서 사용된 테이블과 서브쿼리 결과를 조인
  • IN 연산자를 주로 사용, EXISTS 연산자도 사용 가능
  • 서브쿼리 SELECT절에 아무 컬럼을 명시해도 괜찮다.
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
);

안티조인

  • 세미조인과 비슷하나 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
);
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
);