MySQL에서 datetime 타입의 컬럼을 다룰 때, 시간 정보는 제외하고 날짜 단위로만 그룹화해야 하는 경우가 자주 발생합니다. 예를 들어 일별 게시글 수를 집계하거나 하루에 여러 번 저장된 로그 데이터를 정리할 때가 대표적입니다.
이럴 때는 MySQL 내장 함수인 DATE()를 활용하면 간단하게 해결할 수 있습니다. DATE() 함수는 datetime 값에서 시간 부분을 잘라내고 날짜(YYYY-MM-DD)만 반환하기 때문에, 이 값을 기준으로 그룹화하면 됩니다.
기본 문법
SELECT * FROM yourTableName GROUP BY DATE(yourColumnName);
예제 테이블 생성
실제 동작을 확인하기 위해 먼저 테스트용 테이블을 만들어 보겠습니다.
mysql> CREATE TABLE groupByDateDemo (
-> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> UserName VARCHAR(20),
-> UserPostDatetime DATETIME
-> );
Query OK, 0 rows affected (0.53 sec)샘플 데이터 삽입
INSERT 문을 사용해 몇 개의 레코드를 추가합니다. 같은 날짜에 서로 다른 시간대의 데이터가 포함되도록 구성했습니다.
mysql> INSERT INTO groupByDateDemo(UserName, UserPostDatetime) VALUES('Larry', '2018-01-02 13:45:40');
Query OK, 1 row affected (0.18 sec)
mysql> INSERT INTO groupByDateDemo(UserName, UserPostDatetime) VALUES('Mike', '2018-01-02 13:45:40');
Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO groupByDateDemo(UserName, UserPostDatetime) VALUES('Sam', '2019-01-28 12:30:34');
Query OK, 1 row affected (0.33 sec)
mysql> INSERT INTO groupByDateDemo(UserName, UserPostDatetime) VALUES('David', '2019-02-10 11:35:54');
Query OK, 1 row affected (0.18 sec)
mysql> INSERT INTO groupByDateDemo(UserName, UserPostDatetime) VALUES('Maxwell', '2019-02-10 11:35:54');
Query OK, 1 row affected (0.21 sec)전체 데이터 조회
먼저 SELECT 문으로 테이블의 모든 레코드를 확인해 보겠습니다.
mysql> SELECT * FROM groupByDateDemo;
실행 결과는 다음과 같습니다.
+----+----------+---------------------+ | Id | UserName | UserPostDatetime | +----+----------+---------------------+ | 1 | Larry | 2018-01-02 13:45:40 | | 2 | Mike | 2018-01-02 13:45:40 | | 3 | Sam | 2019-01-28 12:30:34 | | 4 | David | 2019-02-10 11:35:54 | | 5 | Maxwell | 2019-02-10 11:35:54 | +----+----------+---------------------+ 5 rows in set (0.00 sec)
총 5개의 레코드가 있으며, 2018-01-02와 2019-02-10에는 각각 두 건씩 중복된 날짜가 존재합니다.
날짜 기준 GROUP BY 실행
이제 DATE() 함수를 적용해 날짜별로 그룹화해 보겠습니다.
mysql> SELECT * FROM groupByDateDemo
-> GROUP BY DATE(UserPostDatetime);결과는 다음과 같습니다.
+----+----------+---------------------+ | Id | UserName | UserPostDatetime | +----+----------+---------------------+ | 1 | Larry | 2018-01-02 13:45:40 | | 3 | Sam | 2019-01-28 12:30:34 | | 4 | David | 2019-02-10 11:35:54 | +----+----------+---------------------+ 3 rows in set (0.00 sec)
시간까지 포함했을 때는 5개였던 레코드가, 날짜 기준으로 그룹화하자 고유한 날짜 3개만 남은 것을 확인할 수 있습니다. 각 그룹에서는 해당 날짜에 가장 먼저 저장된 레코드 하나가 대표값으로 반환됩니다.
추가 팁: 집계와 함께 활용하기
실무에서는 단순히 그룹을 나누는 것보다 COUNT(), MAX() 같은 집계 함수와 함께 사용하는 경우가 많습니다. 예를 들어 일별 게시 수를 구하려면 다음과 같이 작성할 수 있습니다.
SELECT DATE(UserPostDatetime) AS PostDate,
COUNT(*) AS PostCount
FROM groupByDateDemo
GROUP BY DATE(UserPostDatetime);또한 월별·연도별 집계가 필요하다면 DATE_FORMAT() 함수를 사용해 DATE_FORMAT(UserPostDatetime, '%Y-%m')처럼 원하는 단위로 그룹화할 수 있습니다.