MySQL에서 로그인 시간처럼 날짜와 시간이 저장된 데이터를 다루다 보면, 오늘 날짜(현재 일, 월, 연도)에 해당하는 레코드만 조회해야 하는 경우가 자주 있습니다. 예를 들어 사용자의 로그인 기록을 저장한 테이블이 있다면, 오늘 접속한 사용자, 이번 달에 접속한 사용자, 올해 접속한 사용자를 각각 필터링할 수 있어야겠죠.
이 글에서는 YEAR(), MONTH(), DAY() 함수와 NOW() 함수를 조합하여 현재 날짜 기준으로 레코드를 필터링하는 방법을 단계별로 알아보겠습니다.
1. 샘플 테이블 생성
먼저 사용자 로그인 정보를 저장할 테이블을 생성합니다. UserId는 자동 증가되는 기본키로 설정하고, UserLoginTime은 datetime 타입으로 선언합니다.
mysql> create table userLoginInformation
-> (
-> UserId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> UserName varchar(20),
-> UserLoginTime datetime
-> );
Query OK, 0 rows affected (0.79 sec)
2. 샘플 데이터 삽입
INSERT 문을 사용해 여러 사용자의 로그인 기록을 입력합니다.
mysql> insert into userLoginInformation(UserName,UserLoginTime) values('John','2016-02-12');
Query OK, 1 row affected (0.18 sec)
mysql> insert into userLoginInformation(UserName,UserLoginTime) values('Carol','2019-01-31');
Query OK, 1 row affected (0.16 sec)
mysql> insert into userLoginInformation(UserName,UserLoginTime) values('Bob','2019-02-19');
Query OK, 1 row affected (0.12 sec)
mysql> insert into userLoginInformation(UserName,UserLoginTime) values('Sam','2018-02-19');
Query OK, 1 row affected (0.16 sec)
mysql> insert into userLoginInformation(UserName,UserLoginTime) values('Larry','2017-04-18');
Query OK, 1 row affected (0.18 sec)3. 전체 데이터 확인
SELECT 문으로 테이블에 저장된 모든 레코드를 조회해 보겠습니다.
mysql> select *from userLoginInformation;
실행 결과는 다음과 같습니다.
+--------+----------+---------------------+
| UserId | UserName | UserLoginTime |
+--------+----------+---------------------+
| 1 | John | 2016-02-12 00:00:00 |
| 2 | Carol | 2019-01-31 00:00:00 |
| 3 | Bob | 2019-02-19 00:00:00 |
| 4 | Sam | 2018-02-19 00:00:00 |
| 5 | Larry | 2017-04-18 00:00:00 |
+--------+----------+---------------------+
5 rows in set (0.00 sec)
4. 현재 연도 기준으로 필터링하기
현재 연도에 해당하는 레코드만 조회하려면 YEAR() 함수와 NOW() 함수를 함께 사용합니다. NOW()는 현재 날짜와 시간을 반환하며, YEAR(NOW())는 그중 연도 부분만 추출합니다.
mysql> select *from userLoginInformation where YEAR(UserLoginTime)=YEAR(now());
현재 연도가 2019년이라면 결과는 다음과 같습니다.
+--------+----------+---------------------+
| UserId | UserName | UserLoginTime |
+--------+----------+---------------------+
| 2 | Carol | 2019-01-31 00:00:00 |
| 3 | Bob | 2019-02-19 00:00:00 |
+--------+----------+---------------------+
2 rows in set (0.00 sec)
연도가 2019년인 Carol과 Bob의 레코드만 정상적으로 조회된 것을 확인할 수 있습니다.
5. 현재 월 및 일 기준으로도 필터링 가능
같은 방식으로 MONTH()나 DAY() 함수를 사용하면 현재 월 또는 현재 일에 해당하는 레코드도 쉽게 추출할 수 있습니다.
현재 월 기준 조회
mysql> select *from userLoginInformation where MONTH(UserLoginTime)=MONTH(now());
현재 일 기준 조회
mysql> select *from userLoginInformation where DAY(UserLoginTime)=DAY(now());
6. 성능을 고려한 대안: 범위 조건 활용
WHERE 절에서 컬럼에 함수를 적용하면(YEAR(UserLoginTime)=YEAR(NOW())) 해당 컬럼에 인덱스가 있어도 제대로 활용되지 못할 수 있습니다. 데이터 양이 많다면 아래처럼 날짜 범위 조건을 사용하는 것이 성능 면에서 더 유리합니다.
-- 현재 연도 기준
SELECT * FROM userLoginInformation
WHERE UserLoginTime >= MAKEDATE(YEAR(NOW()), 1)
AND UserLoginTime < MAKEDATE(YEAR(NOW()) + 1, 1);
이 방식은 컬럼 값을 가공하지 않고 조건을 걸기 때문에 인덱스를 효율적으로 사용할 수 있다는 장점이 있습니다.
마무리
정리하면, MySQL에서 현재 날짜 기준으로 레코드를 필터링하는 핵심은 다음과 같습니다.
- 연도:
WHERE YEAR(컬럼) = YEAR(NOW()) - 월:
WHERE MONTH(컬럼) = MONTH(NOW()) - 일:
WHERE DAY(컬럼) = DAY(NOW()) - 대량 데이터: 범위 조건(>=, <)으로 인덱스 활용 극대화
이 패턴들을 익혀두면 로그 분석, 통계 집계, 대시보드용 실시간 조회 등 다양한 상황에서 유용하게 활용할 수 있습니다.