공공부하자개발 · 영어 학습 노트
SQL
SQL 중급서브쿼리·조인·함수·DDL·인덱스0/11 완료
  • 01서브쿼리: 스칼라·인라인 뷰·상관 서브쿼리, DB별 차이
  • 02EXISTS·IN·NOT IN 과 NULL 함정
  • 03조인 심화: INNER·OUTER·SELF·CROSS, Oracle (+)
  • 04집합 연산: UNION·UNION ALL·INTERSECT·MINUS/EXCEPT
  • 05조건 로직: CASE·DECODE·IIF
  • 06NULL 처리 함수
  • 07문자·날짜 함수 DB별 비교
  • 08DDL 과 제약 조건
  • 09인덱스 기초
  • 10집계와 GROUP BY·HAVING
  • 11뷰·시퀀스·자동 증가
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › SQL 중급 › 01 / 11

서브쿼리: 스칼라·인라인 뷰·상관 서브쿼리, DB별 차이

섹션 6진행 0 / 11
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6정리‹ 이전다음 ›

4. 응용 변형 예제

소스: sql-src/mid_01_subquery/03_dialects.sql. 표준 문법으로는 DB마다 똑같이 동작하지만, 상위 N 조회와 인라인 뷰 별칭 표기는 방언 차이가 있습니다.

기능 Oracle · Tibero MySQL MSSQL
상위 N 행 인라인 뷰 + ROWNUM LIMIT n TOP n
인라인 뷰 별칭 선택, AS 쓰면 오류 필수, AS 선택 필수, AS 선택

표준 문법인 OFFSET n ROWS FETCH NEXT m ROWS ONLY 는 Oracle 12c·MSSQL 2012 부터 됩니다. MySQL 은 이 문법이 없고 LIMIT 만 씁니다. 페이징 전체는 실무 01 에서 다룹니다.

변형 1: 표준 — 스칼라 서브쿼리가 여러 행을 반환하면 오류

sql
-- 표준
SELECT
       name
     , (SELECT sal FROM emp WHERE dept = '개발') AS one_sal
  FROM emp
 WHERE dept = '개발';
text
예상 오류: Scalar subquery contains more than one row

개발 부서는 3명이라 서브쿼리가 3행을 반환합니다. 스칼라 서브쿼리는 1행만 허용하므로 오류가 납니다. 부서 조건을 빼먹고 전체를 서브쿼리에 넣었을 때 흔히 나는 실수입니다.

변형 2: Oracle · Tibero — 인라인 뷰 + ROWNUM

sql
-- Oracle · Tibero
SET MODE Oracle;
SELECT
       name
     , sal
  FROM (
        SELECT
               name
             , sal
          FROM emp
         ORDER BY sal DESC
       ) t
 WHERE ROWNUM <= 3;
text
NAME   | SAL
-------+----
김대표 | 900
이팀장 | 650
정팀장 | 600
(3행)

ROWNUM 은 정렬 전 원본 순서에 매겨지므로, 정렬 결과에서 상위 N을 뽑으려면 먼저 인라인 뷰로 정렬을 끝내야 합니다. ORDER BY 없이 바로 WHERE ROWNUM <= 3 을 쓰면 정렬 안 된 임의의 3행이 나옵니다.

주의

실제 Oracle 은 인라인 뷰 별칭 앞에 AS 를 쓰면 문법 오류입니다(FROM (...) t 는 되지만 FROM (...) AS t 는 안 됩니다). H2 는 이 제약을 검사하지 않고 두 표기를 모두 실행합니다. 그래서 이 오류는 H2 로 재현되지 않으며 문법 검토만 했습니다.

변형 3: MySQL — LIMIT, 파생 테이블 별칭

sql
-- MySQL
SET MODE MySQL;
SELECT
       t.dept
     , t.avg_sal
  FROM (
        SELECT
               dept
             , AVG(sal) AS avg_sal
          FROM emp
         GROUP BY dept
       ) t
 WHERE t.avg_sal > 400
 ORDER BY t.avg_sal DESC;

SELECT
       name
     , sal
  FROM emp
 ORDER BY sal DESC
 LIMIT 3;
text
DEPT | AVG_SAL
-----+--------
경영 | 900.0
개발 | 500.0
지원 | 500.0
영업 | 440.0
인사 | 425.0
(5행)

NAME   | SAL
-------+----
김대표 | 900
이팀장 | 650
정팀장 | 600
(3행)

실제 MySQL 은 파생 테이블(FROM 절 서브쿼리)에 별칭이 없으면 오류를 냅니다. H2 는 별칭 없이도 통과시키므로 이 오류는 재현되지 않고 문법 검토만 했습니다. 예제는 항상 별칭을 붙인 형태로 실었습니다.

변형 4: MSSQL — TOP, 상관 서브쿼리와 조합

sql
-- MSSQL
SET MODE MSSQLServer;
SELECT TOP 3
       name
     , sal
  FROM emp
 ORDER BY sal DESC;

SELECT
       t.name
     , t.sal
     , t.dept_avg
  FROM (
        SELECT
               name
             , sal
             , (SELECT AVG(sal) FROM emp x WHERE x.dept = e.dept) AS dept_avg
          FROM emp e
       ) t
 WHERE t.sal > t.dept_avg
 ORDER BY t.dept_avg DESC;
text
NAME   | SAL
-------+----
김대표 | 900
이팀장 | 650
정팀장 | 600
(3행)

NAME   | SAL | DEPT_AVG
-------+-----+---------
이팀장 | 650 | 500.0
정팀장 | 600 | 440.0
서팀장 | 550 | 425.0
(3행)

TOP n 은 SELECT 바로 뒤에 붙는다는 점이 Oracle·MySQL 과 다릅니다. 두 번째 문장은 인라인 뷰 안에 상관 서브쿼리를 넣어 부서 평균보다 많이 받는 사람만 걸렀습니다. 서브쿼리 종류는 섞어 쓸 수 있습니다.

주의

실제 MSSQL 에서 INT 컬럼의 AVG 는 정수로 잘립니다. 위 425.0 은 425 가 됩니다. 소수점이 필요하면 AVG(sal * 1.0) 처럼 먼저 소수로 바꿉니다.

응용 변형 예제
  • 변형 1: 표준 — 스칼라 서브쿼리가 여러 행을 반환하면 오류
  • 변형 2: Oracle · Tibero — 인라인 뷰 + ROWNUM
  • 변형 3: MySQL — LIMIT, 파생 테이블 별칭
  • 변형 4: MSSQL — TOP, 상관 서브쿼리와 조합
이전 섹션3 코드 예제4 / 6다음 섹션5 자주 하는 실수 (Tip)