SQL日付関数完全ガイド|DATE型の取得・抽出・変換・計算まで徹底解説!

データベース・SQL

「データベースで昨日の売上データを取りたいけど、どうやって書くの?」
「日付の計算がうまくいかなくて、エラーが出てしまう…」
「SQLで月末だけのデータを抽出したいけど、方法がわからない…」

そんな悩みを持ったことはありませんか?

**SQL(エスキューエル)**でデータを扱うとき、日付の操作はとても重要です。
売上の分析、ログの集計、スケジュールの管理など、ほとんどの業務で日付を使った処理が必要になります。

でも、日付の関数はたくさんあって、データベースの種類によっても書き方が違うので、初心者の方には難しく感じるかもしれません。

この記事では、SQLでの日付操作の方法を、プログラミング初心者の方にもわかりやすく説明します。よく使われる4つのデータベース(MySQL、PostgreSQL、SQL Server、Oracle)に対応した書き方を、実際の例と一緒に紹介します。

スポンサーリンク

SQLと日付について

日付データの基本

日付データとは?

  • データベースに保存される日付や時間の情報
  • 例:「2024年6月25日」「14時30分」「2024-06-25 14:30:00」
  • 普通の文字列とは違い、計算や比較ができる

日付データの形式

  • DATE:日付のみ(2024-06-25)
  • TIME:時間のみ(14:30:00)
  • DATETIME:日付と時間(2024-06-25 14:30:00)
  • TIMESTAMP:日付と時間(システムで自動管理)

なぜ日付関数が必要?

日付関数でできること

  • 今日の日付を自動的に取得
  • 昨日や1週間前のデータを抽出
  • 2つの日付の差を計算
  • 日付の表示形式を変更
  • 月末や年度末だけのデータを取得

使用例

  • 今月の売上合計を計算
  • 期限切れの商品を確認
  • 毎月のレポートを自動作成
  • 年齢や勤続年数を計算

主要データベースの紹介

この記事では、以下の4つのデータベースでの書き方を説明します。

MySQL(マイエスキューエル)

  • 特徴:無料で使えて、世界中で人気
  • 使用例:ウェブサイト、小規模なシステム
  • メリット:かんたんに始められる

PostgreSQL(ポストグレスキューエル)

  • 特徴:高機能で安定している
  • 使用例:企業のシステム、データ分析
  • メリット:複雑な処理が得意

SQL Server(エスキューエル サーバー)

  • 特徴:マイクロソフト社製
  • 使用例:Windowsを使う企業
  • メリット:他のマイクロソフト製品との連携が良い

Oracle(オラクル)

  • 特徴:大企業でよく使われる
  • 使用例:銀行、保険会社などの大規模システム
  • メリット:大量のデータを高速処理

現在の日付と時間を取得する

まずは、「今日」や「今の時間」を取得する方法から学びましょう。

現在の日時を取得

MySQL

-- 現在の日付と時間
SELECT NOW();
-- 結果例: 2024-06-25 14:30:00

-- 現在の日付のみ
SELECT CURDATE();
-- 結果例: 2024-06-25

-- 現在の時間のみ
SELECT CURTIME();
-- 結果例: 14:30:00

PostgreSQL

-- 現在の日付と時間
SELECT NOW();
-- 結果例: 2024-06-25 14:30:00+09

-- 現在の日付のみ
SELECT CURRENT_DATE;
-- 結果例: 2024-06-25

-- 現在の時間のみ
SELECT CURRENT_TIME;
-- 結果例: 14:30:00+09

SQL Server

-- 現在の日付と時間
SELECT GETDATE();
-- 結果例: 2024-06-25 14:30:00.123

-- 現在の日付のみ
SELECT CONVERT(date, GETDATE());
-- 結果例: 2024-06-25

-- 現在の時間のみ
SELECT CONVERT(time, GETDATE());
-- 結果例: 14:30:00.123

Oracle

-- 現在の日付と時間
SELECT SYSDATE FROM dual;
-- 結果例: 2024-06-25 14:30:00

-- 現在の日付のみ(時間を0時0分0秒にする)
SELECT TRUNC(SYSDATE) FROM dual;
-- 結果例: 2024-06-25 00:00:00

-- 現在の時間のみ(文字列として)
SELECT TO_CHAR(SYSDATE, 'HH24:MI:SS') FROM dual;
-- 結果例: 14:30:00

実際の使用例

-- 注文テーブルに今日の日付で新しい注文を追加(MySQL)
INSERT INTO orders (customer_id, order_date, total_amount)
VALUES (123, NOW(), 15000);

-- 今日作成されたユーザーを確認(PostgreSQL)
SELECT * FROM users 
WHERE created_at >= CURRENT_DATE;

日付から年・月・日を取り出す

日付データから、年、月、日の部分だけを取り出す方法を学びましょう。

年・月・日の抽出

MySQL

-- 注文テーブルから年、月、日を取り出す
SELECT 
    order_id,
    order_date,
    YEAR(order_date) as 注文年,
    MONTH(order_date) as 注文月,
    DAY(order_date) as 注文日
FROM orders;

-- 使用例の結果
-- order_id | order_date | 注文年 | 注文月 | 注文日
-- 1        | 2024-06-25 | 2024   | 6      | 25

PostgreSQL

-- EXTRACT関数を使用
SELECT 
    order_id,
    order_date,
    EXTRACT(YEAR FROM order_date) as 注文年,
    EXTRACT(MONTH FROM order_date) as 注文月,
    EXTRACT(DAY FROM order_date) as 注文日
FROM orders;

SQL Server

-- DATEPART関数を使用
SELECT 
    order_id,
    order_date,
    DATEPART(YEAR, order_date) as 注文年,
    DATEPART(MONTH, order_date) as 注文月,
    DATEPART(DAY, order_date) as 注文日
FROM orders;

-- またはYEAR、MONTH、DAY関数も使用可能
SELECT 
    YEAR(order_date) as 注文年,
    MONTH(order_date) as 注文月,
    DAY(order_date) as 注文日
FROM orders;

Oracle

-- EXTRACT関数を使用
SELECT 
    order_id,
    order_date,
    EXTRACT(YEAR FROM order_date) as 注文年,
    EXTRACT(MONTH FROM order_date) as 注文月,
    EXTRACT(DAY FROM order_date) as 注文日
FROM orders;

実用的な使用例

-- 2024年の注文だけを取得(MySQL)
SELECT * FROM orders 
WHERE YEAR(order_date) = 2024;

-- 6月の売上合計を計算(PostgreSQL)
SELECT SUM(total_amount) as 六月売上
FROM orders 
WHERE EXTRACT(MONTH FROM order_date) = 6;

-- 各月の注文件数を集計(SQL Server)
SELECT 
    DATEPART(MONTH, order_date) as 月,
    COUNT(*) as 注文件数
FROM orders 
GROUP BY DATEPART(MONTH, order_date)
ORDER BY 月;

日付の計算(足し算・引き算)

日付に日数や月数を足したり引いたりする方法を学びましょう。

日数の加算・減算

MySQL

-- 今日から7日後
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY) as 一週間後;
-- 結果例: 2024-07-02 14:30:00

-- 今日から1日前(昨日)
SELECT DATE_SUB(NOW(), INTERVAL 1 DAY) as 昨日;
-- 結果例: 2024-06-24 14:30:00

-- 別の書き方
SELECT NOW() + INTERVAL 7 DAY as 一週間後;
SELECT NOW() - INTERVAL 1 DAY as 昨日;

PostgreSQL

-- 今日から7日後
SELECT NOW() + INTERVAL '7 days' as 一週間後;

-- 昨日
SELECT NOW() - INTERVAL '1 day' as 昨日;

-- 1ヶ月後
SELECT NOW() + INTERVAL '1 month' as 来月;

-- 1年前
SELECT NOW() - INTERVAL '1 year' as 去年;

SQL Server

-- DATEADD関数を使用
-- 今日から7日後
SELECT DATEADD(DAY, 7, GETDATE()) as 一週間後;

-- 昨日
SELECT DATEADD(DAY, -1, GETDATE()) as 昨日;

-- 1ヶ月後
SELECT DATEADD(MONTH, 1, GETDATE()) as 来月;

-- 3時間後
SELECT DATEADD(HOUR, 3, GETDATE()) as 三時間後;

Oracle

-- 日数の場合は直接数値を加算・減算
SELECT SYSDATE + 7 as 一週間後 FROM dual;
SELECT SYSDATE - 1 as 昨日 FROM dual;

-- 月や年の場合はINTERVAL句を使用
SELECT SYSDATE + INTERVAL '1' MONTH as 来月 FROM dual;
SELECT SYSDATE + INTERVAL '1' YEAR as 来年 FROM dual;

実用的な使用例

-- 昨日の注文一覧を取得(MySQL)
SELECT * FROM orders
WHERE DATE(order_date) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);

-- 30日以内の注文を取得(PostgreSQL)
SELECT * FROM orders
WHERE order_date >= NOW() - INTERVAL '30 days';

-- 来月期限切れの商品を取得(SQL Server)
SELECT * FROM products
WHERE expiry_date BETWEEN GETDATE() AND DATEADD(MONTH, 1, GETDATE());

-- 1週間後の予定を取得(Oracle)
SELECT * FROM schedules
WHERE schedule_date = SYSDATE + 7;

2つの日付の差を計算する

2つの日付の間がどれくらい離れているかを計算する方法を学びましょう。

日付の差分計算

MySQL

-- 2つの日付の差(日数)
SELECT DATEDIFF('2024-07-01', '2024-06-01') as 日数差;
-- 結果: 30

-- 時間の差も含めて計算
SELECT TIMESTAMPDIFF(HOUR, '2024-06-25 10:00:00', '2024-06-25 15:30:00') as 時間差;
-- 結果: 5

-- 年の差
SELECT TIMESTAMPDIFF(YEAR, '2020-01-01', '2024-01-01') as 年数差;
-- 結果: 4

PostgreSQL

-- AGE関数で詳細な差分を取得
SELECT AGE('2024-07-01', '2024-06-01') as 期間差;
-- 結果: 1 mon

-- 日数の差
SELECT '2024-07-01'::date - '2024-06-01'::date as 日数差;
-- 結果: 30

-- 年齢計算の例
SELECT AGE('2024-06-25', '1990-03-15') as 年齢;
-- 結果: 34 years 3 mons 10 days

SQL Server

-- DATEDIFF関数で差分を計算
SELECT DATEDIFF(DAY, '2024-06-01', '2024-07-01') as 日数差;
-- 結果: 30

SELECT DATEDIFF(MONTH, '2024-01-01', '2024-06-01') as 月数差;
-- 結果: 5

SELECT DATEDIFF(YEAR, '2020-01-01', '2024-01-01') as 年数差;
-- 結果: 4

-- 時間の差
SELECT DATEDIFF(HOUR, '2024-06-25 10:00:00', '2024-06-25 15:30:00') as 時間差;
-- 結果: 5

Oracle

-- 日数の差(直接計算)
SELECT TO_DATE('2024-07-01', 'YYYY-MM-DD') - TO_DATE('2024-06-01', 'YYYY-MM-DD') as 日数差
FROM dual;
-- 結果: 30

-- 月数の差
SELECT MONTHS_BETWEEN(TO_DATE('2024-07-01', 'YYYY-MM-DD'), TO_DATE('2024-06-01', 'YYYY-MM-DD')) as 月数差
FROM dual;
-- 結果: 1

実用的な使用例

-- 注文から配送までの日数を計算(MySQL)
SELECT 
    order_id,
    order_date,
    shipped_date,
    DATEDIFF(shipped_date, order_date) as 配送日数
FROM orders
WHERE shipped_date IS NOT NULL;

-- 勤続年数を計算(PostgreSQL)
SELECT 
    employee_id,
    name,
    hire_date,
    EXTRACT(YEAR FROM AGE(CURRENT_DATE, hire_date)) as 勤続年数
FROM employees;

-- 期限まで何日かを計算(SQL Server)
SELECT 
    task_id,
    task_name,
    due_date,
    DATEDIFF(DAY, GETDATE(), due_date) as 残り日数
FROM tasks
WHERE due_date >= GETDATE();

曜日・週・四半期を取得する

日付から曜日や週番号、四半期を取得する方法を学びましょう。

曜日の取得

MySQL

-- 曜日名を取得
SELECT DAYNAME(NOW()) as 曜日名;
-- 結果例: Tuesday

-- 曜日番号を取得(1=月曜日、7=日曜日)
SELECT DAYOFWEEK(NOW()) as 曜日番号;
-- 結果例: 3

-- 週番号を取得
SELECT WEEK(NOW()) as 週番号;
-- 結果例: 26

-- 四半期を取得
SELECT QUARTER(NOW()) as 四半期;
-- 結果例: 2

PostgreSQL

-- 曜日名を取得
SELECT TO_CHAR(NOW(), 'Day') as 曜日名;
-- 結果例: Tuesday

-- 曜日番号を取得(0=日曜日、6=土曜日)
SELECT EXTRACT(DOW FROM NOW()) as 曜日番号;
-- 結果例: 2

-- 週番号を取得
SELECT EXTRACT(WEEK FROM NOW()) as 週番号;
-- 結果例: 26

-- 四半期を取得
SELECT EXTRACT(QUARTER FROM NOW()) as 四半期;
-- 結果例: 2

SQL Server

-- 曜日名を取得
SELECT DATENAME(WEEKDAY, GETDATE()) as 曜日名;
-- 結果例: Tuesday

-- 曜日番号を取得
SELECT DATEPART(WEEKDAY, GETDATE()) as 曜日番号;
-- 結果例: 3

-- 週番号を取得
SELECT DATEPART(WEEK, GETDATE()) as 週番号;
-- 結果例: 26

-- 四半期を取得
SELECT DATEPART(QUARTER, GETDATE()) as 四半期;
-- 結果例: 2

Oracle

-- 曜日名を取得
SELECT TO_CHAR(SYSDATE, 'DAY') as 曜日名 FROM dual;
-- 結果例: TUESDAY

-- 曜日番号を取得(1=日曜日、7=土曜日)
SELECT TO_CHAR(SYSDATE, 'D') as 曜日番号 FROM dual;
-- 結果例: 3

-- 週番号を取得
SELECT TO_CHAR(SYSDATE, 'WW') as 週番号 FROM dual;
-- 結果例: 26

-- 四半期を取得
SELECT TO_CHAR(SYSDATE, 'Q') as 四半期 FROM dual;
-- 結果例: 2

実用的な使用例

-- 曜日別の売上集計(MySQL)
SELECT 
    DAYNAME(order_date) as 曜日,
    COUNT(*) as 注文件数,
    SUM(total_amount) as 売上合計
FROM orders
GROUP BY DAYNAME(order_date), DAYOFWEEK(order_date)
ORDER BY DAYOFWEEK(order_date);

-- 平日のみのデータを取得(PostgreSQL)
SELECT * FROM orders
WHERE EXTRACT(DOW FROM order_date) BETWEEN 1 AND 5;

-- 四半期別の売上レポート(SQL Server)
SELECT 
    DATEPART(YEAR, order_date) as 年,
    DATEPART(QUARTER, order_date) as 四半期,
    SUM(total_amount) as 売上合計
FROM orders
GROUP BY DATEPART(YEAR, order_date), DATEPART(QUARTER, order_date)
ORDER BY 年, 四半期;

日付の表示形式を変更する

日付を見やすい形式に変更する方法を学びましょう。

基本的なフォーマット

MySQL

-- 様々な形式で日付を表示
SELECT 
    NOW() as 元の形式,
    DATE_FORMAT(NOW(), '%Y/%m/%d') as 年月日,
    DATE_FORMAT(NOW(), '%Y年%m月%d日') as 日本語形式,
    DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') as 標準形式,
    DATE_FORMAT(NOW(), '%W, %M %d, %Y') as 英語形式
FROM dual;

-- 結果例:
-- 元の形式: 2024-06-25 14:30:00
-- 年月日: 2024/06/25
-- 日本語形式: 2024年06月25日
-- 標準形式: 2024-06-25 14:30:00
-- 英語形式: Tuesday, June 25, 2024

PostgreSQL

-- TO_CHAR関数で様々な形式に変換
SELECT 
    NOW() as 元の形式,
    TO_CHAR(NOW(), 'YYYY/MM/DD') as 年月日,
    TO_CHAR(NOW(), 'YYYY"年"MM"月"DD"日"') as 日本語形式,
    TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS') as 標準形式,
    TO_CHAR(NOW(), 'Day, Month DD, YYYY') as 英語形式
FROM dual;

SQL Server

-- FORMAT関数で様々な形式に変換
SELECT 
    GETDATE() as 元の形式,
    FORMAT(GETDATE(), 'yyyy/MM/dd') as 年月日,
    FORMAT(GETDATE(), 'yyyy年MM月dd日') as 日本語形式,
    FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss') as 標準形式,
    FORMAT(GETDATE(), 'dddd, MMMM dd, yyyy') as 英語形式;

-- CONVERT関数を使った方法
SELECT 
    CONVERT(varchar, GETDATE(), 111) as 年月日1,  -- 2024/06/25
    CONVERT(varchar, GETDATE(), 120) as 標準形式; -- 2024-06-25 14:30:00

Oracle

-- TO_CHAR関数で様々な形式に変換
SELECT 
    SYSDATE as 元の形式,
    TO_CHAR(SYSDATE, 'YYYY/MM/DD') as 年月日,
    TO_CHAR(SYSDATE, 'YYYY"年"MM"月"DD"日"') as 日本語形式,
    TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') as 標準形式,
    TO_CHAR(SYSDATE, 'Day, Month DD, YYYY') as 英語形式
FROM dual;

よく使うフォーマットパターン

MySQL DATE_FORMAT パターン

  • %Y : 4桁の年 (2024)
  • %y : 2桁の年 (24)
  • %m : 月 (01-12)
  • %d : 日 (01-31)
  • %H : 時間 (00-23)
  • %i : 分 (00-59)
  • %s : 秒 (00-59)
  • %W : 曜日名 (Tuesday)

PostgreSQL TO_CHAR パターン

  • YYYY : 4桁の年
  • MM : 月
  • DD : 日
  • HH24 : 時間 (24時間制)
  • MI : 分
  • SS : 秒
  • Day : 曜日名

実用的な使用例

-- レポート用の見やすい日付表示(MySQL)
SELECT 
    order_id,
    DATE_FORMAT(order_date, '%Y年%m月%d日') as 注文日,
    customer_name,
    total_amount
FROM orders
ORDER BY order_date DESC;

-- ログの時刻を見やすく表示(PostgreSQL)
SELECT 
    log_id,
    TO_CHAR(created_at, 'YYYY-MM-DD HH24:MI:SS') as 作成日時,
    message
FROM logs
WHERE created_at >= CURRENT_DATE;

-- 月次レポート用の表示(SQL Server)
SELECT 
    FORMAT(order_date, 'yyyy年MM月') as 年月,
    COUNT(*) as 注文件数,
    SUM(total_amount) as 売上合計
FROM orders
GROUP BY FORMAT(order_date, 'yyyy年MM月')
ORDER BY FORMAT(order_date, 'yyyy年MM月');

実用的な応用例

実際の業務でよく使われる日付処理の例を紹介します。

期間指定での検索

-- 今月のデータを取得(MySQL)
SELECT * FROM orders
WHERE YEAR(order_date) = YEAR(NOW()) 
  AND MONTH(order_date) = MONTH(NOW());

-- 先月のデータを取得(PostgreSQL)
SELECT * FROM orders
WHERE order_date >= date_trunc('month', CURRENT_DATE - interval '1 month')
  AND order_date < date_trunc('month', CURRENT_DATE);

-- 今四半期のデータを取得(SQL Server)
SELECT * FROM orders
WHERE DATEPART(QUARTER, order_date) = DATEPART(QUARTER, GETDATE())
  AND DATEPART(YEAR, order_date) = DATEPART(YEAR, GETDATE());

-- 今年のデータを取得(Oracle)
SELECT * FROM orders
WHERE EXTRACT(YEAR FROM order_date) = EXTRACT(YEAR FROM SYSDATE);

月末・月初の処理

-- 各月の最初の日を取得(MySQL)
SELECT DATE_FORMAT(order_date, '%Y-%m-01') as 月初日
FROM orders
GROUP BY DATE_FORMAT(order_date, '%Y-%m-01');

-- 各月の最後の日を取得(PostgreSQL)
SELECT date_trunc('month', order_date) + interval '1 month - 1 day' as 月末日
FROM orders
GROUP BY date_trunc('month', order_date);

-- 月末のデータのみ抽出(SQL Server)
SELECT * FROM orders
WHERE order_date = EOMONTH(order_date);

-- 月初の処理(Oracle)
SELECT TRUNC(order_date, 'MM') as 月初日
FROM orders
GROUP BY TRUNC(order_date, 'MM');

年齢・期間の計算

-- 顧客の年齢を計算(MySQL)
SELECT 
    customer_id,
    name,
    birth_date,
    TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) as 年齢
FROM customers;

-- 商品の在庫日数を計算(PostgreSQL)
SELECT 
    product_id,
    product_name,
    arrival_date,
    EXTRACT(DAY FROM (CURRENT_DATE - arrival_date)) as 在庫日数
FROM products;

-- 従業員の勤続年数を計算(SQL Server)
SELECT 
    employee_id,
    name,
    hire_date,
    DATEDIFF(YEAR, hire_date, GETDATE()) as 勤続年数
FROM employees;

-- 契約の残り期間を計算(Oracle)
SELECT 
    contract_id,
    customer_name,
    end_date,
    CEIL(end_date - SYSDATE) as 残り日数
FROM contracts
WHERE end_date > SYSDATE;

営業日の計算

-- 平日のみの売上を集計(MySQL)
SELECT 
    DATE(order_date) as 日付,
    SUM(total_amount) as 売上
FROM orders
WHERE DAYOFWEEK(order_date) BETWEEN 2 AND 6  -- 月曜日から金曜日
GROUP BY DATE(order_date);

-- 土日の売上を集計(PostgreSQL)
SELECT 
    DATE(order_date) as 日付,
    SUM(total_amount) as 休日売上
FROM orders
WHERE EXTRACT(DOW FROM order_date) IN (0, 6)  -- 日曜日と土曜日
GROUP BY DATE(order_date);

-- 月曜日の売上傾向を分析(SQL Server)
SELECT 
    DATEPART(WEEK, order_date) as 週番号,
    SUM(total_amount) as 月曜売上
FROM orders
WHERE DATENAME(WEEKDAY, order_date) = 'Monday'
GROUP BY DATEPART(WEEK, order_date);

よくあるエラーと対処法

日付関数を使うときによく起こるエラーと、その解決方法を紹介します。

文字列と日付の混同

よくあるエラー

-- 間違った例
SELECT * FROM orders WHERE order_date = '2024/06/25';

正しい書き方

-- MySQL
SELECT * FROM orders WHERE order_date = '2024-06-25';

-- PostgreSQL
SELECT * FROM orders WHERE order_date = '2024-06-25'::date;

-- SQL Server
SELECT * FROM orders WHERE order_date = '2024-06-25';

-- Oracle
SELECT * FROM orders WHERE order_date = TO_DATE('2024-06-25', 'YYYY-MM-DD');

NULLの処理

-- NULLがある場合の安全な処理(MySQL)
SELECT 
    order_id,
    order_date,
    shipped_date,
    CASE 
        WHEN shipped_date IS NULL THEN '未配送'
        ELSE CONCAT(DATEDIFF(shipped_date, order_date), '日')
    END as 配送日数
FROM orders;

-- COALESCEを使った安全な処理(PostgreSQL)
SELECT 
    customer_id,
    name,
    birth_date,
    COALESCE(birth_date, CURRENT_DATE) as 安全な生年月日
FROM customers;

タイムゾーンの問題

-- タイムゾーンを考慮した処理(PostgreSQL)
SELECT 
    order_id,
    order_date AT TIME ZONE 'Asia/Tokyo' as 日本時間
FROM orders;

-- SQL Serverでのタイムゾーン処理
SELECT 
    order_id,
    order_date AT TIME ZONE 'Tokyo Standard Time' as 日本時間
FROM orders;

パフォーマンス向上のコツ

日付関数を使うときに、処理速度を上げるためのコツを紹介します。

インデックスの活用

-- 効率的な日付検索(インデックスを活用)
-- 良い例:日付列にそのまま条件を指定
SELECT * FROM orders 
WHERE order_date >= '2024-06-01' 
  AND order_date < '2024-07-01';

-- 悪い例:関数を日付列に適用(インデックスが使われない)
SELECT * FROM orders 
WHERE YEAR(order_date) = 2024 AND MONTH(order_date) = 6;

効率的な期間指定

-- 今月のデータを効率的に取得(MySQL)
SELECT * FROM orders
WHERE order_date >= DATE_FORMAT(NOW(), '%Y-%m-01')
  AND order_date < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);

-- 先週のデータを効率的に取得(PostgreSQL)
SELECT * FROM orders
WHERE order_date >= date_trunc('week', CURRENT_DATE - interval '1 week')
  AND order_date < date_trunc('week', CURRENT_DATE);

データベース別の特徴と使い分け

各データベースの日付処理の特徴をまとめます。

MySQL

特徴

  • 直感的でわかりやすい関数名
  • DATE_ADD、DATE_SUBなど、英語として自然
  • タイムゾーン処理が比較的シンプル

おすすめの場面

  • 初心者の学習
  • ウェブアプリケーション
  • 中小規模のシステム

PostgreSQL

特徴

  • 高機能で柔軟な日付処理
  • INTERVAL句が強力
  • 標準SQLに準拠

おすすめの場面

  • 複雑なデータ分析
  • 高精度な日時計算が必要
  • 大規模なデータ処理

SQL Server

特徴

  • マイクロソフト製品との連携が良い
  • 豊富な日付関数
  • 企業向けの機能が充実

おすすめの場面

  • Windows環境の企業
  • .NETアプリケーション
  • 既存のマイクロソフト環境

Oracle

特徴

  • 非常に高機能
  • 大量データの高速処理
  • 独自の関数が多い

おすすめの場面

  • 大企業のシステム
  • 金融・保険業界
  • 超大量データの処理

まとめ

SQLでの日付処理について、基本から応用まで詳しく説明してきました。

重要なポイント

  • データベースごとに関数が異なる:MySQL、PostgreSQL、SQL Server、Oracleで書き方が違う
  • 基本操作を押さえる:取得、抽出、計算、フォーマットの4つが基本
  • 実用例で理解:実際の業務で使う場面を想像しながら学習
  • エラー対策も大切:NULL処理やタイムゾーンに注意

データベース別の使い分け

  • MySQL:初心者におすすめ、直感的な関数名
  • PostgreSQL:高機能、標準SQL準拠
  • SQL Server:マイクロソフト環境に最適
  • Oracle:大企業向け、超高性能

よく使う処理パターン

  1. 現在日時の取得:NOW()、GETDATE()、SYSDATE
  2. 日付の計算:INTERVAL、DATEADD、直接加算
  3. 期間検索:BETWEEN、比較演算子
  4. フォーマット:DATE_FORMAT、TO_CHAR、FORMAT

コメント

タイトルとURLをコピーしました