MySQL에서 쿼리 결과의 특정 열 값을 마치 열 이름(컬럼명)처럼 표시하고 싶다면 CASE 문을 활용하면 됩니다. 이는 흔히 '피벗(Pivot)'이라고 불리는 기법으로, 행 단위로 저장된 데이터를 열 형태로 재구성할 때 매우 유용합니다.
기본 문법
열 값을 열 이름으로 바꾸는 기본적인 문법은 다음과 같습니다.
SELECT yourIdColumnName,
MAX(CASE WHEN yourColumnName1 = 'yourValue1' THEN yourColumnName2 ELSE NULL END) AS 'yourValue1',
MAX(CASE WHEN yourColumnName1 = 'yourValue2' THEN yourColumnName2 ELSE NULL END) AS 'yourValue2',
MAX(CASE WHEN yourColumnName1 = 'yourValue3' THEN yourColumnName2 ELSE NULL END) AS 'yourValue3'
FROM valueAsColumn
GROUP BY yourIdColumnName
ORDER BY yourIdColumnName;핵심은 조건에 따라 값을 반환하는 CASE 문과, 그룹별로 하나의 값만 남기는 MAX 함수를 함께 사용한다는 점입니다. GROUP BY로 기준 열(UserId 등)을 묶으면, 각 값이 해당 열 이름 아래로 배치됩니다.
예제 테이블 생성
문법을 실제로 이해하기 위해 먼저 테이블을 생성해 보겠습니다.
mysql> CREATE TABLE valueAsColumn
-> (
-> UserId INT,
-> UserColumn1 VARCHAR(10),
-> UserColumn2 VARCHAR(10)
-> );
Query OK, 0 rows affected (0.75 sec)데이터 삽입
이제 INSERT 명령어로 몇 개의 레코드를 추가합니다.
mysql> INSERT INTO valueAsColumn VALUES(0,'John','A+'); Query OK, 1 row affected (0.18 sec) mysql> INSERT INTO valueAsColumn VALUES(0,'Carol','B'); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO valueAsColumn VALUES(0,'Sam','C'); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO valueAsColumn VALUES(1,'John','D'); Query OK, 1 row affected (0.20 sec) mysql> INSERT INTO valueAsColumn VALUES(1,'Carol','A'); Query OK, 1 row affected (0.20 sec) mysql> INSERT INTO valueAsColumn VALUES(1,'Carol','C'); Query OK, 1 row affected (0.15 sec)
저장된 데이터 확인
SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> SELECT * FROM valueAsColumn;
실행 결과는 다음과 같습니다.
+--------+-------------+-------------+ | UserId | UserColumn1 | UserColumn2 | +--------+-------------+-------------+ | 0 | John | A+ | | 0 | Carol | B | | 0 | Sam | C | | 1 | John | D | | 1 | Carol | A | | 1 | Carol | C | +--------+-------------+-------------+ 6 rows in set (0.00 sec)
열 값을 열 이름으로 변환하는 쿼리
이제 본격적으로 UserColumn1의 값(John, Carol, Sam)을 열 이름으로 변환하는 쿼리를 실행해 보겠습니다.
mysql> SELECT UserId,
-> MAX(CASE WHEN (UserColumn1='John') THEN UserColumn2 ELSE NULL END) AS 'John',
-> MAX(CASE WHEN (UserColumn1='Carol') THEN UserColumn2 ELSE NULL END) AS 'Carol',
-> MAX(CASE WHEN (UserColumn1='Sam') THEN UserColumn2 ELSE NULL END) AS 'Sam'
-> FROM valueAsColumn
-> GROUP BY UserId
-> ORDER BY UserId;실행 결과는 다음과 같습니다.
+--------+------+-------+------+ | UserId | John | Carol | Sam | +--------+------+-------+------+ | 0 | A+ | B | C | | 1 | D | C | NULL | +--------+------+-------+------+ 2 rows in set (0.00 sec)
결과 해석
출력 결과를 보면 UserId를 기준으로 데이터가 그룹화되었고, 원래 행으로 저장되어 있던 이름(John, Carol, Sam)이 각각 독립된 열 이름으로 변환된 것을 확인할 수 있습니다. 예를 들어 UserId가 0인 경우 John은 'A+', Carol은 'B', Sam은 'C' 값을 가지며, UserId가 1인 경우에는 Sam에 해당하는 데이터가 없으므로 NULL이 표시됩니다.
이처럼 CASE 문과 집계 함수(MAX, SUM 등)를 조합하면 별도의 피벗 도구 없이도 MySQL에서 손쉽게 행을 열로 변환할 수 있습니다. 다만 변환할 열 이름이 사전에 정해져 있어야 한다는 점, 그리고 동적 피벗이 필요한 경우 prepared statement와 결합해야 한다는 점은 참고하시기 바랍니다.