개요
MySQL에서 이번 달과 올해의 시작일 이후에 충전된 바우처 값의 총합을 계산하려면 MONTH() 함수와 YEAR() 함수를 활용하면 됩니다. 이 두 함수는 각각 날짜 값에서 월과 연도를 추출해 주기 때문에, 현재 날짜와 비교하는 조건을 손쉽게 작성할 수 있습니다.
아래에서 예제 테이블 생성부터 데이터 삽입, 그리고 최종 집계 쿼리까지 단계별로 살펴보겠습니다.
1. 예제 테이블 생성하기
먼저 바우처 값과 충전 날짜를 저장할 테이블을 생성합니다.
mysql> create table DemoTable1562
-> (
-> VoucherValue int,
-> RechargeDate date
-> );
Query OK, 0 rows affected (1.40 sec)
2. 샘플 데이터 삽입하기
INSERT 문을 사용해 몇 개의 레코드를 추가합니다.
mysql> insert into DemoTable1562 values(149,'2019-10-21');
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable1562 values(199,'2019-10-13');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable1562 values(399,'2018-10-13');
Query OK, 1 row affected (0.25 sec)
mysql> insert into DemoTable1562 values(450,'2019-10-13');
Query OK, 1 row affected (0.20 sec)
3. 저장된 데이터 확인하기
SELECT 문으로 테이블의 전체 레코드를 조회해 보겠습니다.
mysql> select * from DemoTable1562;
실행 결과는 다음과 같습니다.
+--------------+--------------+
| VoucherValue | RechargeDate |
+--------------+--------------+
| 149 | 2019-10-21 |
| 199 | 2019-10-13 |
| 399 | 2018-10-13 |
| 450 | 2019-10-13 |
+--------------+--------------+
4 rows in set (0.00 sec)
4. 현재 날짜 확인하기
CURDATE() 함수를 사용하면 현재 시스템 날짜를 확인할 수 있습니다.
mysql> select curdate();
+------------+
| curdate() |
+------------+
| 2019-10-13 |
+------------+
1 row in set (0.00 sec)
5. 월 및 연도 시작일 이후 바우처 합계 계산하기
이제 핵심인 집계 쿼리입니다. SUM() 함수와 함께 MONTH(), YEAR() 함수를 사용하여, 충전 날짜의 월과 연도가 현재 날짜의 월·연도와 일치하는 레코드만 필터링한 후 바우처 값을 모두 더합니다.
mysql> select sum(VoucherValue) from DemoTable1562
-> where month(RechargeDate)=month(curdate())
-> and year(RechargeDate)=year(curdate());
실행 결과는 다음과 같습니다.
+-------------------+
| sum(VoucherValue) |
+-------------------+
+-------------------+
1 row in set (0.00 sec)
결과 분석
현재 날짜가 2019-10-13이므로, 조건에 맞는 레코드는 다음 세 건입니다.
- 149 (2019-10-21)
- 199 (2019-10-13)
- 450 (2019-10-13)
반면 399(2018-10-13)는 월은 같지만 연도가 2018년으로 다르기 때문에 제외됩니다. 따라서 최종 합계는 149 + 199 + 450 = 798이 됩니다.
참고: 성능 개선 팁
데이터 양이 많은 경우 WHERE 절에서 컬럼에 함수를 적용하면 인덱스를 활용하지 못할 수 있습니다. 이럴 때는 아래처럼 범위 조건으로 변환하면 성능을 개선할 수 있습니다.
select sum(VoucherValue) from DemoTable1562
where RechargeDate >= date_format(curdate(), '%Y-%m-01');
이 방식은 현재 달의 첫날 이후의 모든 레코드를 대상으로 하므로, 결과는 동일하면서도 인덱스 스캔이 가능해 대용량 테이블에서 더 효율적입니다.