> ## 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 BETWEEN

> MySQL BETWEEN 연산자가 범위를 검사하는 방법, 양쪽 경계가 포함되는 이유, 낮은 경계가 먼저 와야 하는 이유, 그리고 조용히 틀리는 날짜 범위입니다.

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

`BETWEEN`은 값이 범위 안에 들어가는지 검사합니다. 비교 2개를 줄여 쓴 것이고, 날짜에서 사람들이 가장 자주 미묘하게 틀리는 절입니다.

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

## BETWEEN의 동작 방식

```sql theme={null}
SELECT COLUMN_LIST
FROM TABLE_NAME
WHERE COLUMN_NAME BETWEEN LOW_BOUND AND HIGH_BOUND;
```

`LOW_BOUND`와 `HIGH_BOUND`를 범위의 양 끝으로 바꾸세요.

`x BETWEEN a AND b`는 `x >= a AND x <= b`를 뜻합니다. 범위는 양쪽 경계를 포함하고, 낮은 경계를 먼저 씁니다.

## 예제

### 숫자 범위

```sql theme={null}
SELECT title, length
FROM film
WHERE length BETWEEN 60 AND 70
ORDER BY length, title
LIMIT 5;
```

```text theme={null}
+-----------------------+--------+
| title                 | length |
+-----------------------+--------+
| BUBBLE GROSSE         |     60 |
| JERSEY SASSY          |     60 |
| MOCKINGBIRD HOLLYWOOD |     60 |
| PHANTOM GLORY         |     60 |
| PITY BOUND            |     60 |
+-----------------------+--------+
5 rows in set (0.00 sec)
```

정확히 60분인 영화가 결과에 들어 있으며, 이것은 낮은 경계가 일치로 간주된다는 것을 보여 줍니다.

### 같은 것을 풀어 쓴 형태

```sql theme={null}
SELECT title, length
FROM film
WHERE length >= 60 AND length <= 70
ORDER BY length, title
LIMIT 5;
```

```text theme={null}
+-----------------------+--------+
| title                 | length |
+-----------------------+--------+
| BUBBLE GROSSE         |     60 |
| JERSEY SASSY          |     60 |
| MOCKINGBIRD HOLLYWOOD |     60 |
| PHANTOM GLORY         |     60 |
| PITY BOUND            |     60 |
+-----------------------+--------+
5 rows in set (0.00 sec)
```

동일한 행입니다. `BETWEEN`은 열 이름을 두 번 쓰는 수고를 덜어 줄 뿐, 그 밖에는 아무것도 하지 않습니다.

### 범위 밖

```sql theme={null}
SELECT title, length
FROM film
WHERE length NOT BETWEEN 60 AND 70
ORDER BY length, title
LIMIT 5;
```

```text theme={null}
+---------------------+--------+
| title               | length |
+---------------------+--------+
| ALIEN CENTER        |     46 |
| IRON MOON           |     46 |
| KWAI HOMEWARD       |     46 |
| LABYRINTH LEAGUE    |     46 |
| RIDGEMONT SUBMARINE |     46 |
+---------------------+--------+
5 rows in set (0.01 sec)
```

`NOT BETWEEN`은 낮은 경계 아래와 높은 경계 위의 행을 유지합니다. 46분은 카탈로그에서 가장 짧은 영화입니다.

## 낮은 경계가 먼저 와야 합니다

`BETWEEN`은 경계를 대신 정렬해 주지 않습니다. 높은 값을 먼저 주면, 70 이상이면서 동시에 60 이하인 숫자를 요구하는 것이 되는데, 그런 숫자는 없습니다.

```sql theme={null}
SELECT title, length
FROM film
WHERE length BETWEEN 70 AND 60
ORDER BY length, title;
```

```text theme={null}
Empty set (0.00 sec)
```

오류도 경고도 없습니다. 일치할 것으로 예상한 범위에서 빈 결과가 나오면, 경계가 뒤바뀌지 않았는지 먼저 확인할 만합니다.

## 날짜에 대한 BETWEEN은 자정에서 멈춥니다

이것이 사람들의 시간을 정말로 잡아먹는 경우이고, 열의 타입에서 시작합니다.

```sql theme={null}
SHOW COLUMNS FROM payment LIKE 'payment_date';
```

```text theme={null}
+--------------+----------+------+-----+---------+-------+
| Field        | Type     | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| payment_date | datetime | NO   |     | NULL    |       |
+--------------+----------+------+-----+---------+-------+
1 row in set (0.00 sec)
```

`payment_date`는 `datetime`이므로, 모든 값이 시각을 담고 있습니다. 시각 없이 쓴 날짜는 그날이 시작되는 자정을 뜻합니다.

```sql theme={null}
SELECT payment_id
FROM payment
WHERE payment_date BETWEEN '2005-05-25' AND '2005-05-26'
ORDER BY payment_id;
```

```text theme={null}
+------------+
| payment_id |
+------------+
|          1 |
|        146 |
|        174 |
...
+------------+
137 rows in set (0.01 sec)
```

이것은 "25일과 26일"로 읽히고 137개의 행을 반환합니다. 같은 2일을 반열린 범위로 요청하면 311개를 반환합니다.

```sql theme={null}
SELECT payment_id
FROM payment
WHERE payment_date >= '2005-05-25' AND payment_date < '2005-05-27'
ORDER BY payment_id;
```

```text theme={null}
+------------+
| payment_id |
+------------+
|          1 |
|        146 |
|        174 |
...
+------------+
311 rows in set (0.00 sec)
```

높은 경계 `'2005-05-26'`은 `2005-05-26 00:00:00`이 되었습니다. 26일 동안 받은 모든 결제는 그 순간보다 늦으므로, `BETWEEN`은 그것들을 모두 제외했습니다. 137개의 행은 25일 하루만의 것이고, 자정 정각에 떨어지는 결제가 있었다면 그것도 포함했을 것입니다.

날짜 범위는 `>= 시작 AND < 끝의 다음 날`로 쓰세요. 이 형태는 열이 시각을 담고 있는지 생각할 필요가 없고, 나중에 열이 시각을 갖게 되어도 계속 올바릅니다.

## 요약

* 범위에는 `BETWEEN`을 사용하고, 양쪽 경계를 포함한다고 예상하세요.
* 뒤바뀐 범위는 아무것과도 일치하지 않으면서 아무 말도 하지 않으므로, 낮은 경계를 먼저 쓰세요.
* `x BETWEEN a AND b`를 `x >= a AND x <= b`로 읽으세요.
* 날짜에는 `BETWEEN` 대신 `>= start AND < day_after_end`를 사용하세요.

## 함께 보기

* [WHERE](https://villagesql.com/docs/ko/tutorial/where.md) — BETWEEN이 들어가는 절
* [연산자](https://villagesql.com/docs/ko/tutorial/operators.md) — BETWEEN이 줄여 쓴 비교들
* [IN](https://villagesql.com/docs/ko/tutorial/in.md) — 범위가 아니라 값 목록 검사하기
* [MySQL의 날짜와 시간 함수](https://villagesql.com/docs/ko/guides/date-time-functions.md) — 범위의 경계 만들기


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