[SQL] 행을 열로 변환하는 방법(PIVOT)

DataBase 관련 콘텐츠 – 옐로우의 세계


학생 성적 관리에서 시험 단위, 과목 단위로 점수를 저장한다. 예를 들어 2025년 8번째 시험은 “2025008”과 같은 시험코드로 관리할 수 있다. 이번 글에서는 시험코드가 포함된 학생 성적 테이블 구조(종적)를 기준으로, 특정 시험에서 학생별 수학·국어·영어 점수를 조회(횡적)하는 방법을 두 가지 방식(CASE, PIVOT)으로 정리하겠다.



(1) 학생 (STUDENT)

  • 학생번호 (PK)
  • 성명
  • 반코드
  • 성별
  • 기타 ……

(2) 학생성적 (STUDENT_SCORE)

  • 시험코드 (PK)
  • 학생번호 (PK)
  • 과목코드 (PK)
  • 성적
  • 기타 ……

즉, 시험코드 + 학생번호 + 과목코드가 학생성적 테이블의 기본키(PK)이다.

과목코드 예시는 다음과 같다:

<과목코드> : <과목명>
1001 : 수학
1002 : 국어
1003 : 영어
1004 : 물리
1005 : 화학
1006 : 생물
1007 : 지구과학
……


CASE 문과 집계 함수를 사용하면 시험 단위로 행 데이터를 열(Column) 단위로 변환할 수 있다. 성적이 없는 경우는 NVL(…, 0) 처리로 0점을 표시할 수 있다.

SELECT s.학생번호
     , s.성명
     , NVL(MAX(CASE WHEN g.과목코드 = '1001' THEN g.성적 END), 0) AS 수학성적
     , NVL(MAX(CASE WHEN g.과목코드 = '1002' THEN g.성적 END), 0) AS 국어성적
     , NVL(MAX(CASE WHEN g.과목코드 = '1003' THEN g.성적 END), 0) AS 영어성적
FROM 학생 s
   LEFT JOIN 학생성적 g
     ON s.학생번호 = g.학생번호
    AND g.시험코드 = '2025008'
    AND g.과목코드 IN ('1001','1002','1003')
GROUP BY s.학생번호, s.성명
ORDER BY s.학생번호;


오라클에서는 PIVOT 절을 사용하면 보다 직관적으로 열 변환을 할 수 있다.
(Oracle Database 11g에서 피벗 연산자를 도입했다. 이 연산자를 사용하면 행을 열로 쉽게 전환할 수 있다.)

SELECT 학생번호
     , 성명
     , NVL(수학성적, 0) AS 수학성적
     , NVL(국어성적, 0) AS 국어성적
     , NVL(영어성적, 0) AS 영어성적
FROM 
   ( 
   SELECT s.학생번호
        , s.성명
        , g.과목코드
        , g.성적 
   FROM 학생 s 
      LEFT JOIN 학생성적 g 
        ON s.학생번호 = g.학생번호 
       AND g.시험코드 = '2025008' 
   ) 
PIVOT 
   ( MAX(성적) 
     FOR 과목코드 IN ('1001' AS 수학성적, '1002' AS 국어성적, '1003' AS 영어성적) 
   ) 
ORDER BY 학생번호;


학생번호성명수학성적국어성적영어성적
10001홍길동958792
10002김철수88900
10003이순이899290
….….


(1) CASE 방식

  • ANSI SQL과 유사하여 범용성이 높음
  • 다른 DBMS에서도 적용 가능

(2) PIVOT 방식

  • 오라클 전용 구문
  • 가독성이 뛰어나고 쿼리가 더 직관적임
  • 성능 최적화
  • JOIN 절에 시험코드와 과목코드 조건을 넣어야 불필요한 데이터 접근을 줄이고 성능을 높일 수 있음



특정 시험코드에 대해 학생별 과목 성적을 조회할 때, 범용성을 원하면 CASE 방식, 오라클 환경에 최적화하고 싶으면 PIVOT 방식을 사용하는 것이 좋다.


How to convert rows to columns (PIVOT) and back again (UNPIVOT) with SQL in Oracle Database

[SQL] 행을 열로 변환하는 방법(PIVOT)

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.

Scroll to top