> ## 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 ORDER BY

> ORDER BY로 MySQL 결과를 정렬하는 방법: 오름차순과 내림차순, 여러 열 한 번에, 별칭으로 정렬, 그리고 NULL 값이 놓이는 자리를 설명합니다.

> [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 →

테이블에는 순서가 없습니다. 행은 서버가 편한 대로 아무 순서로나 돌아오고, 그 순서는 한 번 실행할 때와 다음 번 사이에 바뀔 수 있습니다. `ORDER BY`가 결과의 순서를 결정하는 유일한 것입니다.

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

## ORDER BY의 동작 방식

```sql theme={null}
SELECT COLUMN_LIST
FROM TABLE_NAME
ORDER BY SORT_COLUMN DIRECTION;
```

`SORT_COLUMN`을 정렬 기준 열로 바꾸세요. `DIRECTION`은 가장 작은 것부터인 `ASC` 또는 가장 큰 것부터인 `DESC` 중 하나입니다. 선택 사항이고, 생략하면 `ASC`를 뜻합니다.

## 예제

### 열 하나로 정렬

```sql theme={null}
SELECT title FROM film ORDER BY title;
```

```text theme={null}
+-----------------------------+
| title                       |
+-----------------------------+
| ACADEMY DINOSAUR            |
| ACE GOLDFINGER              |
| ADAPTATION HOLES            |
| AFFAIR PREJUDICE            |
| AFRICAN EGG                 |
...
+-----------------------------+
1000 rows in set (0.01 sec)
```

### 반대로 정렬

```sql theme={null}
SELECT title, rental_rate FROM film ORDER BY rental_rate DESC;
```

```text theme={null}
+-----------------------------+-------------+
| title                       | rental_rate |
+-----------------------------+-------------+
| ACE GOLDFINGER              |        4.99 |
| AIRPLANE SIERRA             |        4.99 |
| AIRPORT POLLOCK             |        4.99 |
| ALADDIN CALENDAR            |        4.99 |
| ALI FOREVER                 |        4.99 |
...
+-----------------------------+-------------+
1000 rows in set (0.00 sec)
```

Sakila는 모든 영화에 단 3가지 요금 중 1가지를 매기고, 336개의 영화가 최고 요금 4.99를 공유합니다. 동점인 그 336개 행 사이의 순서는 이 쿼리가 결정하지 않으므로, 여기 보이는 순서와 다를 수 있습니다.

### 두 번째 열로 동점 깨기

정렬 열을 우선순위 순서로 쉼표로 구분해 나열하세요. 각 열은 자체 방향을 가집니다.

```sql theme={null}
SELECT title, rental_rate, length
FROM film
ORDER BY rental_rate DESC, length;
```

```text theme={null}
+-----------------------------+-------------+--------+
| title                       | rental_rate | length |
+-----------------------------+-------------+--------+
| IRON MOON                   |        4.99 |     46 |
| HANOVER GALAXY              |        4.99 |     47 |
| ACE GOLDFINGER              |        4.99 |     48 |
| MIDSUMMER GROUNDHOG         |        4.99 |     48 |
| PELICAN COMFORTS            |        4.99 |     48 |
...
+-----------------------------+-------------+--------+
1000 rows in set (0.00 sec)
```

`rental_rate`가 여전히 내림차순으로 앞섭니다. 각 요금 안에서는 가장 짧은 영화가 먼저 옵니다. 길이가 같은 영화는 여전히 동점이므로, 완전히 결정된 순서에는 모든 행을 유일하게 만들 만큼의 열이 필요합니다.

### 별칭으로 정렬

`ORDER BY`는 같은 쿼리의 열 별칭을 참조할 수 있습니다.

```sql theme={null}
SELECT title AS film_title FROM film ORDER BY film_title;
```

```text theme={null}
+-----------------------------+
| film_title                  |
+-----------------------------+
| ACADEMY DINOSAUR            |
| ACE GOLDFINGER              |
| ADAPTATION HOLES            |
...
+-----------------------------+
1000 rows in set (0.00 sec)
```

## 별칭은 작은따옴표가 아니라 백틱으로 감싸세요

공백이 든 별칭은 인용 부호로 감싸야 하는데, 여기서 2가지 인용 방식이 갈립니다. 작은따옴표는 이름이 아니라 문자열을 만들고, 고정된 문자열로 정렬하면 아무것도 정렬되지 않습니다.

```sql theme={null}
SELECT title, rental_rate AS 'Rate' FROM film ORDER BY 'Rate';
```

```text theme={null}
+-----------------------------+------+
| title                       | Rate |
+-----------------------------+------+
| ACADEMY DINOSAUR            | 0.99 |
| ACE GOLDFINGER              | 4.99 |
| ADAPTATION HOLES            | 2.99 |
| AFFAIR PREJUDICE            | 2.99 |
| AFRICAN EGG                 | 2.99 |
...
+-----------------------------+------+
1000 rows in set (0.00 sec)
```

요금이 0.99, 4.99, 2.99로 이어지므로, 아무것도 정렬되지 않았습니다. 서버는 `'Rate'`를 4글자 단어로 읽고 모든 행을 같은 값으로 정렬했습니다. 오류도 없고, 경고도 없고, 정렬도 없습니다.

백틱은 별칭을 지정하고, 정렬이 일어납니다:

```sql theme={null}
SELECT title, rental_rate AS `Rate` FROM film ORDER BY `Rate`;
```

```text theme={null}
+-----------------------------+------+
| title                       | Rate |
+-----------------------------+------+
| ACADEMY DINOSAUR            | 0.99 |
| ALAMO VIDEOTAPE             | 0.99 |
| ALASKA PHANTOM              | 0.99 |
| ALICE FANTASIA              | 0.99 |
| ALONE TRIP                  | 0.99 |
...
+-----------------------------+------+
1000 rows in set (0.00 sec)
```

보이는 모든 행이 0.99이므로, 그 행들 사이의 순서도 여기서 결정되지 않습니다.

## NULL이 놓이는 자리

열은 `NULL`을 가질 수 있는데, 값이 전혀 없음을 기록하는 것입니다. 0도 아니고 빈 문자열도 아닙니다. MySQL은 `NULL`을 모든 실제 값보다 작은 것으로 정렬하므로, 오름차순은 NULL을 먼저 놓습니다. `address`의 603개 행 중 4개에 `address2`가 없습니다.

```sql theme={null}
SELECT address_id, address2 FROM address ORDER BY address2;
```

```text theme={null}
+------------+----------+
| address_id | address2 |
+------------+----------+
|          1 | NULL     |
|          2 | NULL     |
|          3 | NULL     |
|          4 | NULL     |
|        303 |          |
|        605 |          |
...
+------------+----------+
603 rows in set (0.00 sec)
```

4개의 NULL 행이 먼저 옵니다. 그 뒤의 행은 빈 문자열을 가지고 있는데, 빈 문자열은 실제 값이므로 `NULL`보다 크고 어떤 텍스트보다 작은 것으로 정렬됩니다. 그 4개의 NULL 행은 서로 동점이므로, 그 사이의 순서는 이 쿼리가 결정하지 않습니다.

`DESC`는 이것을 뒤집고 NULL은 맨 아래로 갑니다. 같은 결과를 반대로 정렬한 것의 끝부분입니다:

```sql theme={null}
SELECT address_id, address2 FROM address ORDER BY address2 DESC;
```

```text theme={null}
+------------+----------+
| address_id | address2 |
+------------+----------+
...
|        532 |          |
|          1 | NULL     |
|          2 | NULL     |
|          3 | NULL     |
|          4 | NULL     |
+------------+----------+
603 rows in set (0.00 sec)
```

## 요약

* 결과의 순서를 결정하려면 `ORDER BY`를 사용하세요. 다른 어떤 것도 순서를 결정하지 않습니다.
* 가장 큰 것부터 보려면 `DESC`를 쓰세요. `ASC`가 기본값입니다.
* 동점을 깨려면 정렬 열 여러 개를 우선순위 순서로 나열하세요.
* 별칭으로 정렬할 때는 백틱으로 감싸세요. 작은따옴표는 문자열을 만듭니다.
* 오름차순 정렬에서는 `NULL`이 먼저, 내림차순 정렬에서는 마지막에 옵니다.

## 함께 보기

* [SELECT](https://villagesql.com/docs/ko/tutorial/select.md) — 정렬되는 문
* [열 별칭](https://villagesql.com/docs/ko/tutorial/column-aliases.md) — 정렬 기준 열에 이름 붙이기
* [LIMIT](https://villagesql.com/docs/ko/tutorial/limit.md) — 정렬된 결과의 처음 몇 행 가져오기
* [MySQL의 페이지네이션](https://villagesql.com/docs/ko/guides/pagination.md) — 큰 테이블에서 정렬의 비용


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