> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL SELECT DISTINCT

> SELECT DISTINCT가 MySQL에서 중복 행을 제거하는 방식, 열 하나가 아니라 SELECT 목록 전체에 적용되는 이유, 그리고 정렬하지 않는 것입니다.

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

`SELECT DISTINCT`는 각 결과 행을 몇 번 나타나든 한 번만 반환합니다. "이 열에 어떤 값이 나타나는가"라는 형태의 질문에 답하는데, 처음 만나는 테이블에 대해 가장 먼저 알고 싶은 것이 흔히 이것입니다.

시작하기 전에 `mysql -u root -p sakila`로 클라이언트를 여세요.

## DISTINCT의 동작 방식

```sql theme={null}
SELECT DISTINCT COLUMN_LIST
FROM TABLE_NAME;
```

`COLUMN_LIST`를 원하는 열로, `TABLE_NAME`을 테이블로 바꾸세요. `DISTINCT`는 `SELECT` 바로 뒤에 오고, 옆에 있는 열이 아니라 SELECT 목록 전체에 적용됩니다. 이 한 가지 사실이 `DISTINCT`에 관한 대부분의 놀라움을 설명합니다.

## 예제

### 한 열에 있는 값

Sakila는 모든 영화에 등급을 매깁니다. 이 쿼리는 어떤 등급이 존재하는지 묻습니다.

```sql theme={null}
SELECT DISTINCT rating FROM film;
```

```text theme={null}
+--------+
| rating |
+--------+
| PG     |
| G      |
| NC-17  |
| PG-13  |
| R      |
+--------+
5 rows in set (0.00 sec)
```

1,000편의 영화에 5개의 등급입니다. 쓸모 있는 순서 없이 도착하는데, `DISTINCT`는 중복을 제거할 뿐 순서에 대해서는 아무것도 말하지 않기 때문입니다. 순서를 원하면 `ORDER BY`를 추가하세요.

### 다른 열

```sql theme={null}
SELECT DISTINCT rental_rate FROM film;
```

```text theme={null}
+-------------+
| rental_rate |
+-------------+
|        0.99 |
|        4.99 |
|        2.99 |
+-------------+
3 rows in set (0.00 sec)
```

카탈로그의 모든 영화는 3가지 요금 중 하나로 가격이 매겨져 있습니다.

### 고유한 조합

2개의 열 이름을 쓰면 각 열의 값을 따로 얻는 것이 아니라 고유한 쌍 각각을 얻습니다.

```sql theme={null}
SELECT DISTINCT rating, rental_rate
FROM film
ORDER BY rating, rental_rate;
```

```text theme={null}
+--------+-------------+
| rating | rental_rate |
+--------+-------------+
| G      |        0.99 |
| G      |        2.99 |
| G      |        4.99 |
| PG     |        0.99 |
| PG     |        2.99 |
| PG     |        4.99 |
| PG-13  |        0.99 |
| PG-13  |        2.99 |
| PG-13  |        4.99 |
| R      |        0.99 |
| R      |        2.99 |
| R      |        4.99 |
| NC-17  |        0.99 |
| NC-17  |        2.99 |
| NC-17  |        4.99 |
+--------+-------------+
15 rows in set (0.00 sec)
```

5개의 등급 곱하기 3개의 요금은 15이고, 모든 조합이 실제로 나타납니다.

## 정렬된 등급이 알파벳순이 아닌 이유

그 결과는 `rating`으로 정렬되었는데도 `G`, `PG`, `PG-13`, `R`, `NC-17` 순입니다. 알파벳순이라면 `NC-17`이 두 번째에 와야 합니다. `ORDER BY`는 제대로 동작했고, 이유는 열의 유형입니다:

`SHOW COLUMNS`는 테이블의 열을 나열하고, `LIKE` 뒤의 패턴이 그것을 1개의 이름으로 좁힙니다.

```sql theme={null}
SHOW COLUMNS FROM film LIKE 'rating';
```

```text theme={null}
+--------+------------------------------------+------+-----+---------+-------+
| Field  | Type                               | Null | Key | Default | Extra |
+--------+------------------------------------+------+-----+---------+-------+
| rating | enum('G','PG','PG-13','R','NC-17') | YES  |     | G       |       |
+--------+------------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)
```

`rating`은 `ENUM`으로, 고정된 값 목록만 받는 열 유형입니다. MySQL은 각 값을 그 목록 안의 위치로 저장하고 위치로 정렬하므로, `ENUM`은 값이 선언된 순서로 정렬됩니다. 여기서는 선언 순서가 가장 덜 제한적인 등급에서 가장 제한적인 등급으로 이어집니다.

## 열을 추가하면 효과가 사라질 수 있습니다

`DISTINCT`는 행 전체를 보기 때문에, 거의 고유한 열을 추가하면 거의 아무것도 제거되지 않습니다.

```sql theme={null}
SELECT DISTINCT rating, title FROM film;
```

```text theme={null}
+--------+-----------------------------+
| rating | title                       |
+--------+-----------------------------+
| PG     | ACADEMY DINOSAUR            |
| G      | ACE GOLDFINGER              |
| NC-17  | ADAPTATION HOLES            |
...
+--------+-----------------------------+
1000 rows in set (0.00 sec)
```

1,000개의 행이 모두 돌아옵니다. 제목이 모두 다르므로 `rating`과 `title`의 쌍도 모두 다르고, 어느 것도 중복이 아닙니다. 여기서 `DISTINCT`는 5개의 행을 줄 수 없는데, 1,000개의 서로 다른 값이 든 열을 요구했기 때문입니다. 많은 행을 등급당 1개로 접는 것은 다른 연산이고, [GROUP BY](https://villagesql.com/docs/ko/tutorial/group-by.md)가 그것을 위한 절입니다.

## 요약

* 각 결과 행을 한 번만 반환하려면 `SELECT DISTINCT`를 쓰세요.
* SELECT 목록의 모든 열에 한꺼번에 적용된다고 예상하세요.
* 고유한 값을 정렬하고 싶으면 `ORDER BY`를 추가하세요.
* `ENUM` 열은 알파벳순이 아니라 선언된 순서로 정렬된다고 예상하세요.

## 함께 보기

* [SELECT](https://villagesql.com/docs/ko/tutorial/select.md) — DISTINCT가 수식하는 문
* [ORDER BY](https://villagesql.com/docs/ko/tutorial/order-by.md) — 고유한 값 정렬하기
* [GROUP BY](https://villagesql.com/docs/ko/tutorial/group-by.md) — 행을 값당 1개로 접고 개수 세기


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.