「日付だけを表示したい」
「YYYY-MM-DD形式で出力したい」
「曜日を表示したい」
──SQLで日時を扱う際、フォーマット(整形)は非常に重要なポイントです。
しかし、データベースの種類や関数の違いによってやり方が微妙に異なるため、初学者には混乱しやすい部分でもあります。
この記事では、SQLでの日時フォーマットの基本的な書き方や、よく使う変換・抽出方法をわかりやすく解説します。
MySQLとPostgreSQLを中心に、実用的なフォーマット例も多数紹介します。
SQLで日時を扱う基本知識

日時データの種類
SQLでは、日時を保存するためのいくつかのデータ型があります。
主な日時データ型
DATE
:年・月・日のみ(例:2025-06-03)DATETIME
:年月日時分秒(例:2025-06-03 14:30:00)TIMESTAMP
:年月日時分秒(タイムゾーン情報も含む)TIME
:時分秒のみ(例:14:30:00)
現在の日時を取得する方法
-- 現在の日時を取得(どちらも同じ結果)
SELECT NOW(); -- MySQL, PostgreSQL
SELECT CURRENT_TIMESTAMP; -- 標準SQL(多くのDBで使用可能)
-- 現在の日付のみ取得
SELECT CURDATE(); -- MySQL
SELECT CURRENT_DATE; -- PostgreSQL, 標準SQL
-- 現在の時刻のみ取得
SELECT CURTIME(); -- MySQL
SELECT CURRENT_TIME; -- PostgreSQL, 標準SQL
実際のデータ例
元のデータ
-- usersテーブル
+----+----------+---------------------+
| id | name | created_at |
+----+----------+---------------------+
| 1 | 田中太郎 | 2025-06-03 14:30:45 |
| 2 | 佐藤花子 | 2025-06-02 09:15:22 |
| 3 | 山田次郎 | 2025-06-01 18:45:10 |
+----+----------+---------------------+
このcreated_at
をいろいろな形式で表示したい場合に、フォーマット関数を使います。
MySQLでの日時フォーマット(DATE_FORMAT)
基本的な書き方
SELECT DATE_FORMAT(日時列, 'フォーマット文字列') AS 表示名
FROM テーブル名;
主なフォーマット文字列
記号 | 意味 | 例 | 説明 |
---|---|---|---|
%Y | 年(4桁) | 2025 | 西暦4桁 |
%y | 年(2桁) | 25 | 西暦下2桁 |
%m | 月(2桁) | 06 | 01-12 |
%c | 月(1-2桁) | 6 | 1-12 |
%M | 月名(英語) | June | 英語の月名 |
%d | 日(2桁) | 03 | 01-31 |
%e | 日(1-2桁) | 3 | 1-31 |
%H | 時(24時間) | 14 | 00-23 |
%h | 時(12時間) | 02 | 01-12 |
%i | 分 | 30 | 00-59 |
%s | 秒 | 45 | 00-59 |
%W | 曜日名(英語) | Tuesday | 英語の曜日名 |
%w | 曜日番号 | 2 | 0=日曜, 1=月曜… |
実際の使用例
年月日の表示
-- 2025-06-03 形式
SELECT
name,
DATE_FORMAT(created_at, '%Y-%m-%d') AS 作成日
FROM users;
時刻の表示
-- 14:30:45 形式
SELECT
name,
DATE_FORMAT(created_at, '%H:%i:%s') AS 作成時刻
FROM users;
日本語風の表示
-- 2025年06月03日 形式
SELECT
name,
DATE_FORMAT(created_at, '%Y年%m月%d日') AS 作成日
FROM users;
曜日を含む表示
-- 2025-06-03 (Tuesday) 形式
SELECT
name,
DATE_FORMAT(created_at, '%Y-%m-%d (%W)') AS 作成日時
FROM users;
12時間表記での表示
-- 2025-06-03 02:30:45 PM 形式
SELECT
name,
DATE_FORMAT(created_at, '%Y-%m-%d %h:%i:%s %p') AS 作成日時
FROM users;
PostgreSQLでの日時フォーマット(TO_CHAR)

基本的な書き方
SELECT TO_CHAR(日時列, 'フォーマット文字列') AS 表示名
FROM テーブル名;
主なフォーマット文字列
記号 | 意味 | 例 | 説明 |
---|---|---|---|
YYYY | 年(4桁) | 2025 | 西暦4桁 |
YY | 年(2桁) | 25 | 西暦下2桁 |
MM | 月(2桁) | 06 | 01-12 |
Month | 月名(英語) | June | 英語の月名 |
DD | 日(2桁) | 03 | 01-31 |
HH24 | 時(24時間) | 14 | 00-23 |
HH12 | 時(12時間) | 02 | 01-12 |
MI | 分 | 30 | 00-59 |
SS | 秒 | 45 | 00-59 |
Day | 曜日名(英語) | Tuesday | 英語の曜日名 |
D | 曜日番号 | 3 | 1=日曜, 2=月曜… |
実際の使用例
年月日の表示
-- 2025-06-03 形式
SELECT
name,
TO_CHAR(created_at, 'YYYY-MM-DD') AS 作成日
FROM users;
時刻の表示
-- 14:30:45 形式
SELECT
name,
TO_CHAR(created_at, 'HH24:MI:SS') AS 作成時刻
FROM users;
曜日を含む表示
-- 2025-06-03 (Tuesday) 形式
SELECT
name,
TO_CHAR(created_at, 'YYYY-MM-DD (Day)') AS 作成日時
FROM users;
データベース別の対応
SQL Server
-- FORMAT関数を使用(SQL Server 2012以降)
SELECT
name,
FORMAT(created_at, 'yyyy-MM-dd') AS 作成日,
FORMAT(created_at, 'HH:mm:ss') AS 作成時刻
FROM users;
-- CONVERT関数を使用
SELECT
name,
CONVERT(VARCHAR, created_at, 23) AS 作成日 -- YYYY-MM-DD形式
FROM users;
Oracle
-- TO_CHAR関数を使用(PostgreSQLと似ている)
SELECT
name,
TO_CHAR(created_at, 'YYYY-MM-DD') AS 作成日,
TO_CHAR(created_at, 'HH24:MI:SS') AS 作成時刻
FROM users;
SQLite
-- strftime関数を使用
SELECT
name,
strftime('%Y-%m-%d', created_at) AS 作成日,
strftime('%H:%M:%S', created_at) AS 作成時刻
FROM users;
よく使うフォーマット実例集

基本的な日付表示
年月日のみ表示
-- MySQL
SELECT DATE_FORMAT(order_date, '%Y-%m-%d') AS 注文日 FROM orders;
-- PostgreSQL
SELECT TO_CHAR(order_date, 'YYYY-MM-DD') AS 注文日 FROM orders;
-- 結果例:2025-06-03
時刻のみ表示
-- MySQL
SELECT DATE_FORMAT(login_time, '%H:%i:%s') AS ログイン時刻 FROM users;
-- PostgreSQL
SELECT TO_CHAR(login_time, 'HH24:MI:SS') AS ログイン時刻 FROM users;
-- 結果例:14:30:45
日本語風の表示
年月日を日本語で
-- MySQL
SELECT DATE_FORMAT(created_at, '%Y年%m月%d日') AS 作成日 FROM posts;
-- PostgreSQL
SELECT TO_CHAR(created_at, 'YYYY年MM月DD日') AS 作成日 FROM posts;
-- 結果例:2025年06月03日
曜日を日本語で(別途変換が必要)
-- MySQL(CASE文で変換)
SELECT
DATE_FORMAT(created_at, '%Y年%m月%d日') AS 作成日,
CASE DATE_FORMAT(created_at, '%w')
WHEN '0' THEN '日曜日'
WHEN '1' THEN '月曜日'
WHEN '2' THEN '火曜日'
WHEN '3' THEN '水曜日'
WHEN '4' THEN '木曜日'
WHEN '5' THEN '金曜日'
WHEN '6' THEN '土曜日'
END AS 曜日
FROM posts;
ビジネスでよく使う形式
レポート用の詳細な日時
-- MySQL
SELECT
id,
customer_name,
DATE_FORMAT(order_datetime, '%Y年%m月%d日 %H時%i分') AS 注文日時
FROM orders;
-- 結果例:2025年06月03日 14時30分
月次レポート用
-- MySQL
SELECT
DATE_FORMAT(sale_date, '%Y年%m月') AS 売上月,
SUM(amount) AS 売上合計
FROM sales
GROUP BY DATE_FORMAT(sale_date, '%Y%m')
ORDER BY sale_date;
-- 結果例:2025年06月
週次レポート用
-- MySQL
SELECT
DATE_FORMAT(created_at, '%Y年第%u週') AS 週,
COUNT(*) AS 登録者数
FROM users
GROUP BY DATE_FORMAT(created_at, '%Y%u')
ORDER BY created_at;
-- 結果例:2025年第23週
時刻の詳細な表示
12時間表記
-- MySQL
SELECT DATE_FORMAT(meeting_time, '%Y-%m-%d %h:%i %p') AS 会議時間 FROM meetings;
-- 結果例:2025-06-03 02:30 PM
秒まで含めた詳細時刻
-- MySQL
SELECT DATE_FORMAT(access_time, '%Y-%m-%d %H:%i:%s.%f') AS アクセス時刻 FROM access_logs;
-- 結果例:2025-06-03 14:30:45.123456
実際の業務での活用例

売上レポートでの使用
-- 月別売上サマリー
SELECT
DATE_FORMAT(sale_date, '%Y年%m月') AS 売上月,
COUNT(*) AS 売上件数,
SUM(amount) AS 売上合計
FROM sales
WHERE sale_date >= '2025-01-01'
GROUP BY DATE_FORMAT(sale_date, '%Y%m')
ORDER BY sale_date;
ログ分析での使用
-- 時間帯別のアクセス分析
SELECT
DATE_FORMAT(access_time, '%H') AS 時間帯,
COUNT(*) AS アクセス数
FROM access_logs
WHERE DATE(access_time) = '2025-06-03'
GROUP BY DATE_FORMAT(access_time, '%H')
ORDER BY 時間帯;
顧客管理での使用
-- 顧客の登録日を見やすく表示
SELECT
customer_id,
customer_name,
DATE_FORMAT(registration_date, '%Y年%m月%d日') AS 登録日,
CASE DATE_FORMAT(registration_date, '%w')
WHEN '0' THEN '日'
WHEN '1' THEN '月'
WHEN '2' THEN '火'
WHEN '3' THEN '水'
WHEN '4' THEN '木'
WHEN '5' THEN '金'
WHEN '6' THEN '土'
END AS 曜日
FROM customers
ORDER BY registration_date DESC;
日時の抽出・計算
特定の部分だけを取り出す
年、月、日を個別に取得
-- MySQL
SELECT
YEAR(created_at) AS 年,
MONTH(created_at) AS 月,
DAY(created_at) AS 日
FROM users;
-- PostgreSQL
SELECT
EXTRACT(YEAR FROM created_at) AS 年,
EXTRACT(MONTH FROM created_at) AS 月,
EXTRACT(DAY FROM created_at) AS 日
FROM users;
週の開始日を取得
-- MySQL(月曜日を週の開始とする)
SELECT
DATE_SUB(created_at, INTERVAL WEEKDAY(created_at) DAY) AS 週開始日
FROM users;
-- PostgreSQL
SELECT
DATE_TRUNC('week', created_at) AS 週開始日
FROM users;
月の最初と最後
-- MySQL
SELECT
DATE_FORMAT(created_at, '%Y-%m-01') AS 月初,
LAST_DAY(created_at) AS 月末
FROM users;
-- PostgreSQL
SELECT
DATE_TRUNC('month', created_at) AS 月初,
DATE_TRUNC('month', created_at) + INTERVAL '1 month' - INTERVAL '1 day' AS 月末
FROM users;
注意点とベストプラクティス
データ型の変化に注意
フォーマット後は文字列になる
-- これは文字列として比較される(注意)
SELECT * FROM users
WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-06-03';
-- これは日付として比較される(推奨)
SELECT * FROM users
WHERE DATE(created_at) = '2025-06-03';
パフォーマンスへの影響
インデックスが効かなくなる例
-- 悪い例:関数を使うとインデックスが効かない
SELECT * FROM orders
WHERE DATE_FORMAT(order_date, '%Y-%m') = '2025-06';
-- 良い例:範囲指定でインデックスを活用
SELECT * FROM orders
WHERE order_date >= '2025-06-01'
AND order_date < '2025-07-01';
タイムゾーンの考慮
MySQLでのタイムゾーン変換
-- UTCから日本時間に変換してフォーマット
SELECT
DATE_FORMAT(CONVERT_TZ(created_at, '+00:00', '+09:00'), '%Y-%m-%d %H:%i:%s') AS 日本時間
FROM users;
PostgreSQLでのタイムゾーン変換
-- UTCから日本時間に変換してフォーマット
SELECT
TO_CHAR(created_at AT TIME ZONE 'JST', 'YYYY-MM-DD HH24:MI:SS') AS 日本時間
FROM users;
NULLの処理
-- NULLの場合の代替表示
SELECT
name,
COALESCE(DATE_FORMAT(updated_at, '%Y-%m-%d'), '未更新') AS 更新日
FROM users;
よくあるエラーと対処法

フォーマット文字の間違い
MySQLとPostgreSQLの混同
-- 間違い:MySQLで PostgreSQL の書式を使用
SELECT DATE_FORMAT(created_at, 'YYYY-MM-DD') FROM users; -- エラー
-- 正しい:MySQL の書式
SELECT DATE_FORMAT(created_at, '%Y-%m-%d') FROM users;
存在しない日付
-- 安全な日付作成
SELECT
CASE
WHEN LAST_DAY(CONCAT(year, '-', month, '-01')) >= CONCAT(year, '-', month, '-', day)
THEN CONCAT(year, '-', month, '-', day)
ELSE NULL
END AS 有効な日付
FROM date_parts;
文字列と日付の混在
-- 文字列を日付に変換してからフォーマット
SELECT
DATE_FORMAT(STR_TO_DATE(date_string, '%Y/%m/%d'), '%Y-%m-%d') AS 整形後
FROM import_data;
高度なテクニック
条件付きフォーマット
-- 古いデータは年月のみ、新しいデータは年月日で表示
SELECT
name,
CASE
WHEN created_at < '2025-01-01' THEN DATE_FORMAT(created_at, '%Y年%m月')
ELSE DATE_FORMAT(created_at, '%Y年%m月%d日')
END AS 作成日
FROM users;
複数の日付フィールドの統合表示
-- 更新日がある場合は更新日、なければ作成日を表示
SELECT
name,
DATE_FORMAT(
COALESCE(updated_at, created_at),
'%Y年%m月%d日'
) AS 最終更新日
FROM posts;
期間の表示
-- 作成から現在までの期間を表示
SELECT
name,
DATE_FORMAT(created_at, '%Y年%m月%d日') AS 作成日,
CONCAT(
TIMESTAMPDIFF(YEAR, created_at, NOW()), '年',
TIMESTAMPDIFF(MONTH, created_at, NOW()) % 12, 'ヶ月'
) AS 経過期間
FROM users;
まとめ
SQLで日時をフォーマットする方法を覚えれば、データ表示の柔軟性と見やすさが格段に向上します。
各データベースの特徴を理解し、目的に応じた整形ができるようになれば、SQLの表現力も一気に広がります。
重要なポイント
- MySQL:
DATE_FORMAT()
関数、%
記号を使用 - PostgreSQL:
TO_CHAR()
関数、英字記号を使用 - 共通注意点:フォーマット後は文字列になる、パフォーマンスに影響する場合がある
使い方のコツ
- よく使うフォーマットはテンプレート化する
- パフォーマンスを考慮して適切に使う
- タイムゾーンを意識する
- NULLの処理を忘れない
活用場面
- レポート出力での見やすい日付表示
- ログ分析での時間帯別集計
- 顧客管理での登録日表示
- 売上分析での期間別集計
コメント