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

MySQL 쿼리에서 연도를 무시하고 날짜 범위로 조회하는 방법

MySQL에서 연도를 무시한 날짜 범위 조회 방법

날짜 범위 조건에서 연도는 제외하고 월·일만 기준으로 데이터를 필터링해야 하는 경우가 있습니다. 예를 들어 어떤 연도든 상관없이 1월 1일부터 3월 31일 사이에 배송된 모든 주문을 조회하고 싶다면, DATE_FORMAT() 함수와 BETWEEN 절을 함께 사용하면 간단하게 해결할 수 있습니다.

이번 글에서는 데모 테이블을 직접 만들어 단계별로 확인해 보겠습니다.

1. 테이블 생성

먼저 배송 날짜(ShippingDate)를 저장할 테이블을 생성합니다.

mysql> create table igonreYearDemo
    -> (
    -> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> ShippingDate date
    -> );
Query OK, 0 rows affected (0.75 sec)

2. 샘플 데이터 입력

INSERT 문을 사용해 서로 다른 연도의 배송 날짜 데이터를 여러 건 입력합니다.

mysql> insert into igonreYearDemo(ShippingDate) values('2016-01-31');
Query OK, 1 row affected (0.16 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2018-01-31');
Query OK, 1 row affected (0.13 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2015-06-23');
Query OK, 1 row affected (0.17 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2015-06-23');
Query OK, 1 row affected (0.15 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2014-02-01');
Query OK, 1 row affected (0.20 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2019-01-31');
Query OK, 1 row affected (0.16 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2019-02-14');
Query OK, 1 row affected (0.11 sec)
mysql> insert into igonreYearDemo(ShippingDate) values('2019-03-12');
Query OK, 1 row affected (0.19 sec)

3. 전체 데이터 확인

SELECT 문으로 테이블에 저장된 모든 레코드를 조회합니다.

mysql> select *from igonreYearDemo;

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

+----+--------------+
| Id | ShippingDate |
+----+--------------+
| 1  | 2016-01-31   |
| 2  | 2018-01-31   |
| 3  | 2015-06-23   |
| 4  | 2015-06-23   |
| 5  | 2014-02-01   |
| 6  | 2019-01-31   |
| 7  | 2019-02-14   |
| 8  | 2019-03-12   |
+----+--------------+
8 rows in set (0.00 sec)

4. 연도를 무시한 날짜 범위 조회 쿼리

핵심은 DATE_FORMAT(tbl.ShippingDate, '%m-%d')입니다. 이 함수는 날짜 값을 '월-일' 형식의 문자열로 변환해 주기 때문에, BETWEEN 절로 '01-01'부터 '03-31' 사이인지 비교하면 연도와 관계없이 해당 기간에 속하는 모든 레코드를 조회할 수 있습니다.

mysql> select *from igonreYearDemo tbl where DATE_FORMAT(tbl.ShippingDate, '%m-%d') between '01-01' and '03-31';

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

+----+--------------+
| Id | ShippingDate |
+----+--------------+
| 1  | 2016-01-31   |
| 2  | 2018-01-31   |
| 5  | 2014-02-01   |
| 6  | 2019-01-31   |
| 7  | 2019-02-14   |
| 8  | 2019-03-12   |
+----+--------------+
6 rows in set (0.00 sec)

결과를 살펴보면 2014년, 2016년, 2018년, 2019년 등 다양한 연도의 데이터 중에서 월·일이 1월 1일부터 3월 31일 사이에 있는 6건만 반환된 것을 확인할 수 있습니다. 반대로 6월 23일처럼 범위를 벗어난 데이터는 연도와 무관하게 모두 제외되었습니다.

참고: 성능 최적화 팁

컬럼에 함수를 적용하면 인덱스를 활용하지 못해 대용량 테이블에서는 조회 속도가 느려질 수 있습니다. 데이터 양이 많다면 월·일 값을 별도 컬럼으로 저장하거나 MySQL 5.7 이상의 생성 컬럼(generated column)에 인덱스를 걸어두는 방식을 고려해 보세요.