MySQL에서 두 열의 고유한(distinct) 조합 선택하기
MySQL에서 두 개의 열에 저장된 값들의 고유한 조합을 추출해야 하는 경우가 종종 있습니다. 예를 들어, 's,t'와 't,s'처럼 순서만 다른 데이터를 하나의 조합으로 취급하고 싶다면 CASE 문을 활용하면 간단하게 해결할 수 있습니다.
이 글에서는 실제 예제 테이블을 만들고, CASE 문을 사용하여 두 열의 고유한 조합을 선택하는 방법을 단계별로 살펴보겠습니다.
1단계: 예제 테이블 생성
먼저 두 개의 문자열 열을 가진 테이블을 생성합니다. 테이블 생성 쿼리는 다음과 같습니다.
mysql> create table select_DistinctTwoColumns
-> (
-> Id int NOT NULL AUTO_INCREMENT,
-> FirstValue char(1),
-> SecondValue char(1),
-> PRIMARY KEY(Id)
-> );
Query OK, 0 rows affected (0.57 sec)
2단계: 샘플 데이터 삽입
INSERT 명령을 사용하여 테이블에 몇 개의 레코드를 추가합니다.
mysql> insert into select_DistinctTwoColumns(FirstValue,SecondValue) values('s','t');
Query OK, 1 row affected (0.12 sec)
mysql> insert into select_DistinctTwoColumns(FirstValue,SecondValue) values('t','u');
Query OK, 1 row affected (0.24 sec)
mysql> insert into select_DistinctTwoColumns(FirstValue,SecondValue) values('u','v');
Query OK, 1 row affected (0.12 sec)
mysql> insert into select_DistinctTwoColumns(FirstValue,SecondValue) values('u','t');
Query OK, 1 row affected (0.16 sec)3단계: 전체 레코드 확인
SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> select *from select_DistinctTwoColumns;
실행 결과는 다음과 같습니다.
+----+------------+-------------+
| Id | FirstValue | SecondValue |
+----+------------+-------------+
| 1 | s | t |
| 2 | t | u |
| 3 | u | v |
| 4 | u | t |
+----+------------+-------------+
4 rows in set (0.00 sec)
여기서 주목할 점은 4번째 행입니다. 'u'와 't'의 조합은 2번째 행의 't'와 'u'와 동일한 값 세트이지만 순서가 반대로 되어 있습니다. 이런 경우 단순히 DISTINCT만으로는 중복을 제거할 수 없습니다.
4단계: CASE 문으로 고유한 조합 선택
CASE 문을 사용하면 두 열의 값을 비교하여 항상 작은 값을 첫 번째 열에, 큰 값을 두 번째 열에 배치함으로써 순서에 관계없이 동일한 조합을 하나로 묶을 수 있습니다.
첫 번째 열 이름은 'FirstValue', 두 번째 열 이름은 'SecondValue'입니다. 쿼리는 다음과 같습니다.
mysql> SELECT distinct
-> CASE
-> WHEN FirstValue<SecondValue THEN FirstValue
-> ELSE SecondValue
-> END AS FirstColumn,
-> CASE
-> WHEN FirstValue > SecondValue THEN FirstValue
-> ELSE SecondValue
-> END AS SecondColumn
-> FROM select_DistinctTwoColumns;
실행 결과는 다음과 같습니다.
+-------------+--------------+
| FirstColumn | SecondColumn |
+-------------+--------------+
| s | t |
| t | u |
| u | v |
+-------------+--------------+
3 rows in set (0.00 sec)
결과 분석 및 핵심 포인트
원래 4개의 행이 있었지만, 결과는 3개의 행만 반환되었습니다. 그 이유는 다음과 같습니다.
(t, u)와 (u, t)는 CASE 문에 의해 모두 (t, u)로 정규화되었기 때문입니다. 즉, 두 값 중 작은 값이 항상 FirstColumn에 오도록 정렬 기준을 통일한 것입니다.
- WHEN FirstValue < SecondValue THEN FirstValue: 첫 번째 값이 더 작으면 그대로 사용하고, 그렇지 않으면 두 번째 값을 반환하여 작은 값을 FirstColumn에 배치합니다.
- WHEN FirstValue > SecondValue THEN FirstValue: 반대로 큰 값을 SecondColumn에 배치합니다.
이 방식은 문자열뿐만 아니라 숫자나 날짜 타입에도 동일하게 적용할 수 있습니다. 두 열의 값 쌍에서 순서를 무시한 고유 조합이 필요하다면 CASE 문을 활용한 이 패턴을 유용하게 사용해 보시기 바랍니다.