MySQL에서 날짜 데이터를 다룰 때 특정 개월 범위에 해당하는 레코드만 추출해야 하는 경우가 자주 있습니다. 예를 들어 작년 7월부터 올해 7월까지의 데이터를 조회하고 싶다면 YEAR(), MONTH(), DATE_SUB() 함수를 조합하면 됩니다.
이 글에서는 실제 예제를 통해 개월 범위 조건으로 레코드를 가져오는 방법을 단계별로 살펴보겠습니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다. 이름(Name)과 마감일(DueDate) 두 개의 컬럼으로 구성된 간단한 테이블입니다.
mysql> create table DemoTable1795 ( Name varchar(20), DueDate date ); Query OK, 0 rows affected (0.00 sec)
2. 샘플 데이터 삽입하기
INSERT 명령을 사용하여 테이블에 테스트용 레코드를 추가합니다.
mysql> insert into DemoTable1795 values('John','2018-07-21');
Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1795 values('Sam','2019-10-21');
Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1795 values('Sam','2019-01-10');
Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1795 values('Mike','2018-12-31');
Query OK, 1 row affected (0.00 sec)3. 전체 레코드 확인하기
SELECT 문을 실행하여 테이블에 저장된 모든 레코드를 먼저 확인해 보겠습니다.
mysql> select * from DemoTable1795;
실행 결과는 다음과 같습니다.
+------+------------+ | Name | DueDate | +------+------------+ | John | 2018-07-21 | | Sam | 2019-10-21 | | Sam | 2019-01-10 | | Mike | 2018-12-31 | +------+------------+ 4 rows in set (0.00 sec)
4. 개월 범위 조건으로 레코드 조회하기
이제 핵심인 개월 범위 조회 쿼리입니다. 아래 쿼리는 작년 7월~12월 또는 올해 1월~7월에 해당하는 레코드를 가져옵니다.
mysql> select * from DemoTable1795 where (YEAR(DueDate) = YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR)) AND MONTH(DueDate) BETWEEN 7 AND 12) OR (YEAR(DueDate) = YEAR(CURRENT_DATE()) AND MONTH(DueDate) BETWEEN 1 AND 7);
실행 결과는 다음과 같습니다.
+------+------------+ | Name | DueDate | +------+------------+ | John | 2018-07-21 | | Sam | 2019-01-10 | | Mike | 2018-12-31 | +------+------------+ 3 rows in set (0.00 sec)
쿼리 동작 원리 살펴보기
위 쿼리가 어떻게 동작하는지 각 부분을 나누어 이해해 보겠습니다.
- DATE_SUB(CURDATE(), INTERVAL 1 YEAR): 현재 날짜에서 1년을 빼서 작년의 오늘 날짜를 구합니다. 이 값에
YEAR()을 적용하면 작년 연도가 됩니다. - YEAR(DueDate) = ... AND MONTH(DueDate) BETWEEN 7 AND 12: 작년 연도이면서 월이 7월부터 12월 사이인 레코드를 필터링합니다.
- OR 이후 조건: 올해(
CURRENT_DATE()) 연도이면서 월이 1월부터 7월 사이인 레코드를 추가로 포함시킵니다.
결과적으로 John(2018-07-21), Sam(2019-01-10), Mike(2018-12-31) 세 개의 레코드가 조건에 해당하며, 2019-10-21은 범위를 벗어나므로 제외됩니다.
마무리
이처럼 YEAR()과 MONTH() 함수를 BETWEEN 연산자와 함께 사용하면 특정 개월 범위의 데이터를 손쉽게 조회할 수 있습니다. 참고로 인덱스가 설정된 날짜 컬럼이라면 함수를 적용하면 인덱스를 활용하지 못할 수 있으므로, 대량의 데이터를 다룰 때는 DueDate >= '2018-07-01' AND DueDate < '2019-08-01'처럼 날짜 범위 비교 방식을 사용하는 것이 성능 면에서 더 유리할 수 있다는 점도 기억해 두면 좋습니다.