Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. SQL辞典
  3. DATE_ADD / DATEDIFF

DATE_ADD / DATEDIFF

日付・日時に対して期間を加算・減算したり、2つの日付の差を求めたりする関数です。

構文
-- 日付に期間を加算します(MySQL)。
SELECT DATE_ADD(日付, INTERVAL 値 単位);

-- 日付から期間を減算します(MySQL)。
SELECT DATE_SUB(日付, INTERVAL 値 単位);

-- 2つの日付の差(日数)を取得します(MySQL)。
SELECT DATEDIFF(日付1, 日付2);

-- 2つの日付・時刻の差を取得します(PostgreSQL)。
SELECT AGE(日付1, 日付2);
構文一覧
構文概要
DATE_ADD(日付, INTERVAL 値 単位)指定した日付に期間を加算した日付を返します(MySQL)。
DATE_SUB(日付, INTERVAL 値 単位)指定した日付から期間を減算した日付を返します(MySQL)。
INTERVAL 値 単位期間を表す式です。単位には DAY・MONTH・YEAR・HOUR・MINUTE・SECOND などが使用できます。
DATEDIFF(日付1, 日付2)日付1から日付2を引いた日数を返します(MySQL)。
AGE(日付1, 日付2)2つの日付の差を年・月・日の形式で返します(PostgreSQL)。
サンプルコード
-- 今日から30日後の日付を取得します。
SELECT DATE_ADD(CURRENT_DATE, INTERVAL 30 DAY) AS deadline;

-- 今日から3ヶ月前の日付を取得します。
SELECT DATE_SUB(CURRENT_DATE, INTERVAL 3 MONTH) AS three_months_ago;

-- 注文日から7日後の配送予定日を算出します。
SELECT order_id, order_date,
       DATE_ADD(order_date, INTERVAL 7 DAY) AS estimated_delivery
FROM orders;

-- 登録日から今日までの経過日数を取得します。
SELECT member_id, name,
       DATEDIFF(CURRENT_DATE, registered_at) AS days_since_joined
FROM members;

-- 30日以上前の注文を取得します。
SELECT order_id, order_date
FROM orders
WHERE order_date <= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY);
実行結果
-- SELECT member_id, name, DATEDIFF(CURRENT_DATE, registered_at) AS days_since_joined FROM members; の結果例
-- +-----------+----------+------------------+
-- | member_id | name     | days_since_joined |
-- +-----------+----------+------------------+
-- |         1 | 田中太郎 |              365 |
-- |         2 | 鈴木花子 |              120 |
-- |         3 | 佐藤一郎 |               30 |
-- +-----------+----------+------------------+
データベース別の書き方

PostgreSQL では『+ INTERVAL』演算子で日付の加算ができます。日付の差は引き算で求めます。

-- 今日から30日後の日付を取得します(PostgreSQL)。
SELECT CURRENT_DATE + INTERVAL '30 days' AS deadline;

-- 2つの日付の差を日数で取得します(PostgreSQL)。
SELECT CURRENT_DATE - registered_at AS days_since_joined FROM members;

-- 年・月・日の形式で差を取得します(PostgreSQL)。
SELECT AGE(CURRENT_DATE, registered_at) FROM members;

Oracle では『+ 数値』で日数を加算できます。月の加算には『ADD_MONTHS』を使用します。

-- 今日から30日後の日付を取得します(Oracle)。
SELECT SYSDATE + 30 AS deadline FROM DUAL;

-- 3ヶ月前の日付を取得します(Oracle)。
SELECT ADD_MONTHS(SYSDATE, -3) AS three_months_ago FROM DUAL;

SQL Server では『DATEADD』で加算、『DATEDIFF』で差を求めます。

-- 今日から30日後の日付を取得します(SQL Server)。
SELECT DATEADD(DAY, 30, GETDATE()) AS deadline;

-- 登録日から今日までの経過日数を取得します(SQL Server)。
SELECT member_id, name,
       DATEDIFF(DAY, registered_at, GETDATE()) AS days_since_joined
FROM members;

SQLite では『date』関数に修飾子を付けて計算します。

-- 今日から30日後の日付を取得します(SQLite)。
SELECT date('now', '+30 days') AS deadline;

-- 3ヶ月前の日付を取得します(SQLite)。
SELECT date('now', '-3 months') AS three_months_ago;
概要

『DATE_ADD』と『DATE_SUB』はMySQL固有の関数ですが、標準SQLの『+ INTERVAL』構文(例:『order_date + INTERVAL '7' DAY』)を使うとPostgreSQLでも動作します。移植性を重視する場合は標準SQLの書き方を選ぶとよいでしょう。

『DATEDIFF(日付1, 日付2)』はMySQLでは日付1 − 日付2の日数を返します。PostgreSQLでは『日付1 - 日付2』と引き算の演算子で整数の日数差を求めることができます。

現在の日付・日時を取得するには『CURRENT_DATE / NOW』を、日付から年月日などの要素を取り出すには『EXTRACT / FORMAT』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。