Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

레코드에 공백이 포함된 경우 MySQL DISTINCT가 올바르게 작동하도록 하는 방법

문제 상황: 공백 때문에 DISTINCT가 제대로 작동하지 않는 경우

MySQL에서 DISTINCT 키워드는 중복된 값을 제거하고 고유한 값만 반환합니다. 그러나 데이터에 앞뒤 공백이 포함되어 있으면 'John'과 'John '처럼 사람 눈에는 같은 값이라도 MySQL은 서로 다른 문자열로 인식합니다. 이럴 때 REPLACE 함수를 함께 사용하면 공백을 제거한 상태로 중복을 깔끔하게 처리할 수 있습니다.

기본 문법

SELECT DISTINCT replace(yourColumnName,' ','') FROM yourTableName;

REPLACE 함수는 첫 번째 인자(컬럼 값)에서 두 번째 인자(공백 ' ')를 찾아 세 번째 인자(빈 문자열 '')로 치환합니다. 공백이 제거된 값을 기준으로 DISTINCT가 적용되기 때문에, 공백 유무와 관계없이 동일한 값은 하나로 묶여 반환됩니다.

실전 예제

1. 테이블 생성

먼저 예제에 사용할 테이블을 생성합니다.

mysql> create table DemoTable
(
    Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Name varchar(20)
);
Query OK, 0 rows affected (0.63 sec)

2. 데이터 삽입

INSERT 명령으로 공백이 섞인 레코드들을 입력합니다.

mysql> insert into DemoTable(Name) values('John ');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable(Name) values(' John ');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable(Name) values('John');
Query OK, 1 row affected (0.09 sec)
mysql> insert into DemoTable(Name) values('Sam');
Query OK, 1 row affected (0.15 sec)
mysql> insert into DemoTable(Name) values('Carol');
Query OK, 1 row affected (0.22 sec)
mysql> insert into DemoTable(Name) values(' Sam');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable(Name) values('Mike ');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable(Name) values('David');
Query OK, 1 row affected (0.17 sec)

3. 전체 레코드 조회

SELECT 문으로 테이블의 모든 레코드를 확인해 보겠습니다.

mysql> select *from DemoTable;

실행 결과는 다음과 같습니다.

+----+-----------+
| Id | Name      |
+----+-----------+
| 1  | John      |
| 2  | John      |
| 3  | John      |
| 4  | Sam       |
| 5  | Carol     |
| 6  | Sam       |
| 7  | Mike      |
| 8  | David     |
+----+-----------+
8 rows in set (0.00 sec)

'John', 'John ', ' John '처럼 공백의 위치만 다른 값들이 서로 다른 레코드로 저장되어 있는 것을 확인할 수 있습니다.

4. 공백을 무시하고 DISTINCT 적용

이제 REPLACE 함수를 활용해 공백을 제거한 뒤 DISTINCT를 적용해 보겠습니다.

mysql> SELECT DISTINCT replace(Name,' ','') FROM DemoTable;

실행 결과는 다음과 같습니다.

+----------------------+
| replace(Name,' ','') |
+----------------------+
| John                 |
| Sam                  |
| Carol                |
| Mike                 |
| David                |
+----------------------+
5 rows in set (0.00 sec)

결과 분석

원래 8개의 레코드가 있었지만, 공백을 제거한 기준으로 중복을 제거하니 5개의 고유한 이름만 반환되었습니다. 'John' 관련 3개 레코드와 'Sam' 관련 2개 레코드가 각각 하나로 합쳐진 것입니다.

추가 팁: TRIM 함수 활용하기

앞뒤 공백만 제거하면 되는 상황이라면 REPLACE 대신 TRIM 함수를 사용하는 것도 좋은 방법입니다.

SELECT DISTINCT TRIM(Name) FROM DemoTable;

TRIM은 문자열 양 끝의 공백만 제거하고, REPLACE는 문자열 내 모든 공백을 제거한다는 차이가 있습니다. 'John Smith'처럼 단어 사이 공백이 의미 있는 데이터라면 TRIM 쪽이 더 안전한 선택입니다.