공든탑앱 열기

서브쿼리

SQLD (SQL 개발자) · 서브쿼리와 집합 연산 · 약 15분

쉽게 말하면

서브쿼리는 질문 안에 들어 있는 작은 질문이에요. '평균보다 급여가 높은 사원'을 찾으려면 먼저 평균을 구해야 하죠. 괄호 안에 평균을 구하는 SELECT를 넣고, 그 답으로 바깥 SELECT가 사원을 골라요. 답이 한 줄인지 여러 줄인지에 따라 함께 쓰는 연산자가 달라져요.

시험용 정의

서브쿼리는 SQL 문 안에 괄호로 넣은 또 하나의 SELECT 문이다. 돌려주는 행 수에 따라 단일행(=, > 등과 함께), 다중행(IN, ANY, ALL, EXISTS), 다중 열 서브쿼리로 나눈다. 바깥 쿼리의 열을 참조하면 연관(상관) 서브쿼리다. 놓이는 위치에 따라 SELECT 절의 스칼라 서브쿼리, FROM 절의 인라인 뷰, WHERE·HAVING 절의 서브쿼리가 있다.

비유로 이해하기

"우리 반 평균보다 키 큰 사람"을 찾으려면 먼저 평균을 구하고(안쪽 질문), 그 답으로 다시 고른다(바깥 질문). 안쪽 질문이 서브쿼리다.

자세히

먼저 알아 둘 말

말뜻
메인쿼리서브쿼리를 품고 있는 바깥쪽 SELECT
단일행 연산자=, <>, >, <, >=, <= : 값 하나와 비교
다중행 연산자IN, ANY(SOME), ALL, EXISTS : 여러 값과 비교
스칼라값 하나(1행 1열)

다중행 연산자

연산자뜻예 (30번 급여: 5000, 3000, 2800, 2600)
IN목록 중 하나와 같다sal IN (…) → 그 네 값 중 하나
> ANY목록 중 하나보다라도 크다 = 최솟값보다 크다> 2600
> ALL목록의 모든 값보다 크다 = 최댓값보다 크다> 5000
< ANY / < ALL최댓값보다 작다 / 최솟값보다 작다< 5000 / < 2600
EXISTS서브쿼리 결과가 한 행이라도 있으면 참값이 아니라 존재 여부만 본다

위치별 서브쿼리

위치이름특징
SELECT 절스칼라 서브쿼리반드시 1행 1열. 0행이면 NULL, 2행 이상이면 오류
FROM 절인라인 뷰결과를 테이블처럼 쓴다. 별칭을 붙여 쓴다. 이 안에서는 ORDER BY도 쓸 수 있다
WHERE·HAVING 절중첩 서브쿼리조건 값을 만든다. HAVING에서는 그룹 비교에 쓴다

연관 서브쿼리

서브쿼리 안에서 바깥 쿼리의 열을 쓰면 연관 서브쿼리다. 바깥 행마다 서브쿼리가 다시 계산된다.

예: 자기 부서 평균보다 급여가 많은 사원 SELECT ename FROM emp e WHERE sal > (SELECT AVG(sal) FROM emp WHERE deptno = e.deptno). 서브쿼리의 e.deptno가 바깥 행의 부서다.

서브쿼리 안에서는 바깥 열을 쓸 수 있지만, 바깥 쿼리는 서브쿼리 안의 열을 쓸 수 없다. 서브쿼리의 결과를 바깥에서 보려면 FROM 절 인라인 뷰나 조인을 쓴다.

시험에 이렇게 나와요

출제 범위·공식 안내 기반

확인 문제

Q1. WHERE sal = (SELECT sal FROM emp WHERE deptno = 20)을 실행하면? (20번 부서는 5명)

  1. 결과가 없다
  2. 오류가 난다
  3. 첫 번째 값으로만 비교한다
  4. 20번 부서 사원과 급여가 같은 사원이 나온다
정답 보기

2번 오류가 난다

= 는 값 하나와 비교하는 단일행 연산자인데 서브쿼리가 여러 행을 돌려줘 오류(ORA-01427)다. 여러 행이면 IN, ANY, ALL 같은 다중행 연산자를 써야 한다.

Q2. 서브쿼리가 (2600, 2800, 3000)을 돌려줄 때 sal < ANY (…)와 같은 조건은?

  1. sal < 3000
  2. sal IN (2600, 2800, 3000)
  3. sal < 2800
  4. sal < 2600
정답 보기

1번 sal < 3000

< ANY는 어느 하나보다만 작으면 되므로 최댓값 3000보다 작다.

Q3. MGR 열에 NULL이 있는 EMP에서 SELECT ename FROM emp WHERE empno NOT IN (SELECT mgr FROM emp)의 결과는?

  1. 결과 없음
  2. 관리자인 사원
  3. 오류
  4. 관리자가 아닌 사원
정답 보기

1번 결과 없음

NOT IN 목록에 NULL이 있으면 <> NULL이 항상 알 수 없음이라 0행. WHERE mgr IS NOT NULL을 서브쿼리에 넣거나 NOT EXISTS를 쓴다.

Q4. SELECT 절에 쓰여 반드시 한 행 한 열을 돌려줘야 하는 서브쿼리는?

  1. 인라인 뷰
  2. 다중 열 서브쿼리
  3. 다중행 서브쿼리
  4. 스칼라 서브쿼리
정답 보기

4번 스칼라 서브쿼리

스칼라 서브쿼리. 결과가 없으면 NULL, 두 행 이상이면 오류.

Q5. 서브쿼리에 대한 설명으로 틀린 것은?

  1. 메인쿼리는 서브쿼리 안의 열을 자유롭게 SELECT할 수 있다
  2. 서브쿼리는 괄호로 감싼다
  3. 연관 서브쿼리는 바깥 쿼리의 열을 참조한다
  4. FROM 절 서브쿼리를 인라인 뷰라고 한다
정답 보기

1번 메인쿼리는 서브쿼리 안의 열을 자유롭게 SELECT할 수 있다

바깥에서는 WHERE 서브쿼리 안의 열을 볼 수 없다. 인라인 뷰로 만들면 볼 수 있다.

헷갈리기 쉬운 O·X

EXISTS 서브쿼리는 SELECT 목록에 무엇을 쓰든 결과가 같다.

정답 보기

O 행이 있는지만 보므로 SELECT 1, SELECT * 모두 같다.

> ALL (서브쿼리)는 서브쿼리 결과의 최솟값보다 크다는 뜻이다.

정답 보기

X 모든 값보다 커야 하므로 최댓값보다 크다.

인라인 뷰 안에서는 ORDER BY를 쓸 수 있다.

정답 보기

O Top N 쿼리에서 정렬한 인라인 뷰에 ROWNUM을 거는 식으로 쓴다.

함께 보면 좋은 개념