MySQLのDATE_FORMATで日付を整形する方法と書式一覧
MySQL で datetime 型のカラムから「日付部分だけ」「年月だけ」を取り出したいときに使うのが DATE_FORMAT 関数です。
使う頻度はそこそこあるのに、書式指定子(%Y や %m など)の組み合わせをいつも検索してしまう……という方も多いのではないでしょうか。
この記事では DATE_FORMAT の基本的な使い方から、よく使う書式指定子の一覧、月別の集計といった実用例までをまとめてご紹介します。
DATE_FORMAT 関数とは
DATE_FORMAT は、date 型 / datetime 型 / timestamp 型の値を、指定した書式の文字列に変換する関数です。
構文は次の通りで、第 2 引数のフォーマット文字列に、出力したい形を指定します。
DATE_FORMAT(日付の値, '書式指定子')例えば '%Y-%m-%d' を指定すると 2025-10-01 のようなハイフン区切りの日付文字列が返ってきます。
日付フォーマットの基本サンプル
下記のような datetime 型のカラムを参照する SELECT 文があるとします。
mysql> SELECT hoge_date FROM hogehoge;
+---------------------+
| 2025-10-01 07:00:00 |
| 2025-10-02 18:00:00 |
+---------------------+年月日(YYYY-MM-DD)で取得する
もっともよく使う、ハイフン区切りの年月日を取得するパターンです。
mysql> SELECT DATE_FORMAT(hoge_date, '%Y-%m-%d') AS tmp_date FROM hogehoge;
+------------+
| 2025-10-01 |
| 2025-10-02 |
+------------+年月(YYYY-MM)だけで取得する
月単位で集計したいときに重宝するのが '%Y-%m' 指定です。
mysql> SELECT DATE_FORMAT(hoge_date, '%Y-%m') AS tmp_date FROM hogehoge;
+---------+
| 2025-10 |
| 2025-10 |
+---------+区切り文字なし(YYYYMMDD)で取得する
ファイル名やバッチ処理のキーに使いたいときなど、区切り文字なしの 8 桁数値として扱いたいケースも多いですよね。
時間まで連結したい場合は %H(24 時間表記の時)を追加するだけなので、用途に合わせてフォーマットを変えられるのが DATE_FORMAT の便利なところです。
mysql> SELECT DATE_FORMAT(hoge_date, '%Y%m%d') AS tmp_date FROM hogehoge;
+----------+
| 20251001 |
| 20251002 |
+----------+
mysql> SELECT DATE_FORMAT(hoge_date, '%Y%m%d%H') AS tmp_date FROM hogehoge;
+------------+
| 2025100107 |
| 2025100218 |
+------------+よく使う書式指定子(フォーマット)一覧
DATE_FORMAT で使える主な書式指定子をまとめました。
大文字と小文字で意味が変わるものがいくつかあるので、ここはコピペ前に一度確認すると安心です。
| 指定子 | 意味 | 出力例 |
|---|---|---|
%Y | 年(4 桁) | 2025 |
%y | 年(2 桁) | 25 |
%m | 月(01〜12、ゼロ埋め) | 03 |
%c | 月(1〜12、ゼロ埋めなし) | 3 |
%M | 月名(英語フル) | March |
%b | 月名(英語省略形) | Mar |
%d | 日(01〜31、ゼロ埋め) | 07 |
%e | 日(1〜31、ゼロ埋めなし) | 7 |
%H | 時(00〜23、24 時間表記) | 09 |
%h / %I | 時(01〜12、12 時間表記) | 09 |
%k | 時(0〜23、ゼロ埋めなし) | 9 |
%i | 分(00〜59) | 05 |
%s / %S | 秒(00〜59) | 42 |
%p | AM または PM | AM |
%T | 時刻(24 時間、hh:mm:ss) | 09:05:42 |
%r | 時刻(12 時間、hh:mm:ss AM/PM) | 09:05:42 AM |
%W | 曜日名(英語フル) | Tuesday |
%a | 曜日名(英語省略形) | Tue |
%w | 曜日番号(0=日曜〜6=土曜) | 2 |
%j | 年内の通算日(001〜366) | 066 |
%U | 第何週(日曜始まり、00〜53) | 10 |
%u | 第何週(月曜始まり、00〜53) | 10 |
もっと網羅的に確認したい場合は、MySQL 公式リファレンスに全指定子の説明がまとまっています。
GROUP BY と組み合わせた集計サンプル
DATE_FORMAT の真価は、datetime 型を任意の粒度に丸めて GROUP BY できる点にあります。
月別の件数を集計する
年月単位でグルーピングすることで、月別件数や月別合計値などをそのまま SQL 側で取得できます。
mysql> SELECT DATE_FORMAT(hoge_date, '%Y-%m') AS tmp_date,
-> COUNT(*) AS tmp_count
-> FROM hogehoge
-> GROUP BY DATE_FORMAT(hoge_date, '%Y-%m');
+---------+---+
| 2025-10 | 2 |
+---------+---+時間帯別(1 時間単位)でグルーピングする
アクセスログを時間帯ごとに集計したい、といったケースでは %H まで含めて GROUP BY すると 1 時間単位で丸められます。
SELECT DATE_FORMAT(hoge_date, '%Y-%m-%d %H:00') AS hour_slot,
COUNT(*) AS tmp_count
FROM hogehoge
GROUP BY DATE_FORMAT(hoge_date, '%Y-%m-%d %H:00')
ORDER BY hour_slot;曜日別に集計する
曜日別の傾向を見たい場合は %w(曜日番号)でグルーピングして、表示用に %W(曜日名)も併記するときれいです。
SELECT DATE_FORMAT(hoge_date, '%w') AS dow_num,
DATE_FORMAT(hoge_date, '%W') AS dow_name,
COUNT(*) AS tmp_count
FROM hogehoge
GROUP BY dow_num, dow_name
ORDER BY dow_num;DATE_FORMAT と DATE 関数の使い分け
「datetime 型から日付部分だけ取りたい」だけなら、実は DATE() 関数でも十分です。
mysql> SELECT DATE(hoge_date) AS tmp_date FROM hogehoge;
+------------+
| 2025-10-01 |
| 2025-10-02 |
+------------+大きな違いは、戻り値の型と書式の自由度です。
DATE():戻り値は date 型。書式は固定でYYYY-MM-DD。DATE_FORMAT():戻り値は 文字列型。書式を自由に変えられる。
日付として後続のクエリで使う・インデックスを効かせたいなら DATE()、表示用や CSV 出力用なら DATE_FORMAT()、というのが基本的な使い分けです。
DB 側で整形するか、アプリ側で整形するか
もちろん、データベースからそのまま datetime 型の値を取得して、アプリ側で整形してもまったく問題ありません。
ですが、出力フォーマットがガチっと決まっている場合は DB 側で整形した方が楽です。
特に、datetime 型を日付ごと・月ごとにグルーピングして集計する場面では、DATE_FORMAT を経由するのがいちばん素直で読みやすい SQL になります。
日付カラムの型はどうするのが良い?
余談ですが、datetime 型なのに時間部分は固定で 00:00:00 しか入らないシステムに遭遇することは、実はけっこう多いものです。
YYYYMMDD を想定した char(8) や、YYYY-MM-DD を文字列で持つ varchar(10) など、プロジェクトによって型はさまざま。
プロジェクト内で統一されていれば実害は少ないものの、いっそのこと date 型でいいような気もしますよね。
意外と date 型を使っているプロジェクトに遭遇する確率が低いのは、空文字にしたいか NULL にしたいかなど、案件ごとに要求が異なるのも一因かもしれません。
まとめ
MySQL の DATE_FORMAT 関数を、書式指定子の一覧と実用サンプル付きで整理しました。
- 日付部分だけ欲しいなら
DATE_FORMAT(col, '%Y-%m-%d')もしくはDATE(col) - 月単位の集計は
'%Y-%m'を GROUP BY するのが定番 - 書式は自由に組み合わせられる(
'%Y%m%d'や'%Y/%m/%d %H:%i'など) - 大文字・小文字で意味が変わる指定子(
%Mと%mなど)に注意
覚えなくても、必要なときにこの記事の指定子一覧から拾って使っていただければ十分です。
