DATEADD (Transact-SQL)

number に指定された間隔 (符号付き整数) を加算した date を返します。この間隔は、指定した date の datepart に加算されます。

Transact-SQL の日付と時刻のデータ型および関数の概要については、「日付と時刻のデータ型および関数 (Transact-SQL)」を参照してください。日付と時刻のデータ型および関数の一般的な例については、「日時データの使用」を参照してください。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

DATEADD (datepart , number, date )

引数

  • datepart
    integer 型の number を、date のどの構成要素に加算するかを指定します。次の表は、datepart 引数に有効なすべての値の一覧です。ユーザー定義変数に相当するものは無効です。

    datepart

    省略形

    year

    yy,yyyy

    quarter

    qq,q

    month

    mm,m

    dayofyear

    dy,y

    day

    dd,d

    week

    wk,ww

    weekday

    dw,w

    hour

    hh

    minute

    mi,n

    second

    ss,s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • number
    date の datepart に加算する値として、int 型に解決可能な式を指定します。ユーザー定義型の変数は有効です。

    小数を含む値を指定した場合、小数部は丸められずに切り捨てられます。

  • date
    time、date、smalldatetime、datetime、datetime2、datetimeoffset のいずれかの値に解決可能な式を指定します。date には、式、列式、ユーザー定義変数、または文字列リテラルを指定できます。式が文字列リテラルの場合は、datetime に解決する必要があります。このあいまいな状態を避けるためには、4 桁の西暦を使用して表記します。2 桁の年の詳細については、「two digit year cutoff オプション」を参照してください。

戻り値の型

文字列リテラルを除き、戻り値のデータ型は、date 引数のデータ型になります。

文字列リテラルの戻り値のデータ型は datetime です。文字列リテラルの秒の小数点以下桁数が 3 桁 (.nnn) を超えた場合またはタイム ゾーン オフセット部分を含んでいた場合、エラーが発生します。

注意注意

date パラメーターに指定した文字列リテラルを明示的にキャストしていない場合、DATEADD を他の日付/時刻関数と共に使用したときに、日/月/年 (dmy) 日付形式を使用するロケールで誤った結果が返されることがあります。

datetime2 型を返す

date パラメーターが datetime2 型の場合、DATEADD は datetime2 型を返します。date パラメーターに文字列リテラルを使用する場合、DATEADD が datetime2 型を返すようにするには、文字列リテラルを datetime2 型に明示的にキャストする必要があります。

datepart 引数

dayofyear、day および weekday は、同じ値を返します。

いずれの datepart も、対応する省略形を指定すると、同じ値が返されます。

datepart に month を指定したとき、date の月の日数が、戻り値の月の日数を超えていて、date の日が戻り値の月に存在しない場合、戻り値の月の最後の日が返されます。たとえば、9 月の日数が 30 日である場合、次の 2 つのステートメントは、2006-09-30 00:00:00.000 を返します。

SELECT DATEADD(month, 1, '2006-08-30')

SELECT DATEADD(month, 1, '2006-08-31')

number 引数に、int の範囲を超える値は指定できません。次のステートメントでは、number 引数が int の範囲を 1 つ超えています。"式をデータ型 int に変換中に演算のオーバーフロー エラーが発生しました。" というエラー メッセージが返されます。

SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');

date 引数を、そのデータ型の範囲外の値に増やすことはできません。次のステートメントでは、date 値に加算される number 値が、date データ型の範囲を超えています。"値を 'datetime' 列に追加したことで、オーバーフローが発生しました。" というエラー メッセージが返されます。

SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');

smalldatetime 値の秒要素は常に 00 になります。date が smalldatetime の場合、次の規則が適用されます。

  • datepart が second で、number が -30 ~ +29 である場合、加算処理は実行されません。

  • datepart が second で、number が -30 より小さく +29 より大きい場合、加算処理は 1 分から実行されます。

  • datepart が millisecond で、number が -30001 ~ +29998 である場合、加算処理は実行されません。

  • datepart が millisecond で、number が -30001 より小さく +29998 より大きい場合、加算処理は 1 分から実行されます。

説明

DATEADD は、選択リストのほか、WHERE 句、HAVING 句、GROUP BY 句、および ORDER BY 句で使用できます。

1 秒未満の秒の有効桁数

date のデータ型が smalldatetime、date、datetime のいずれかである場合、datepart を microsecond や nanosecond にして加算処理を行うことはできません。

ミリ秒の小数点以下桁数は 3 (.123) です。マイクロ秒の小数点以下桁数は 6 (.123456) です。ナノ秒の小数点以下桁数は 9 (.123456789) です。time、datetime2、datetimeoffset の各データ型の最大小数点以下桁数は 7 (.1234567) です。datepart が nanosecond である場合、date の 1 秒未満の秒を増やす前に、number を 100 にする必要があります。number に 1 ~ 49 の値を指定した場合、値は 0 に切り捨てられ、50 ~ 99 の値を指定した場合、値は 100 に切り上げられます。

次のステートメントでは、millisecond、microsecond、または nanosecond の datepart を加算します。

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT '1 millisecond' ,DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2);
/*
Returns:
1 millisecond     2007-01-01 13:10:10.1121111
2 milliseconds    2007-01-01 13:10:10.1131111
1 microsecond     2007-01-01 13:10:10.1111121
2 microseconds    2007-01-01 13:10:10.1111131
49 nanoseconds    2007-01-01 13:10:10.1111111
50 nanoseconds    2007-01-01 13:10:10.1111112
150 nanoseconds   2007-01-01 13:10:10.1111113
*/

タイム ゾーン オフセット

タイム ゾーン オフセットの加算は許可されません。

A. datepart を 1 単位増やす

次の各ステートメントでは、datepart を 1 単位増やしています。

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT 'year', DATEADD(year,1,@datetime2)
UNION ALL
SELECT 'quarter',DATEADD(quarter,1,@datetime2)
UNION ALL
SELECT 'month',DATEADD(month,1,@datetime2)
UNION ALL
SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2)
UNION ALL
SELECT 'day',DATEADD(day,1,@datetime2)
UNION ALL
SELECT 'week',DATEADD(week,1,@datetime2)
UNION ALL
SELECT 'weekday',DATEADD(weekday,1,@datetime2)
UNION ALL
SELECT 'hour',DATEADD(hour,1,@datetime2)
UNION ALL
SELECT 'minute',DATEADD(minute,1,@datetime2)
UNION ALL
SELECT 'second',DATEADD(second,1,@datetime2)
UNION ALL
SELECT 'millisecond',DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT 'microsecond',DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2);
/*
Year         2008-01-01 13:10:10.1111111
quarter      2007-04-01 13:10:10.1111111
month        2007-02-01 13:10:10.1111111
dayofyear    2007-01-02 13:10:10.1111111
day          2007-01-02 13:10:10.1111111
week         2007-01-08 13:10:10.1111111
weekday      2007-01-02 13:10:10.1111111
hour         2007-01-01 14:10:10.1111111
minute       2007-01-01 13:11:10.1111111
second       2007-01-01 13:10:11.1111111
millisecond  2007-01-01 13:10:10.1121111
microsecond  2007-01-01 13:10:10.1111121
nanosecond   2007-01-01 13:10:10.1111111
*/

B. 単一のステートメントで datepart を複数単位増やす

次の各ステートメントでは、number を、上位の datepart への繰り上がりが生じる程度に大きくとって、date の datepart を増やしています。

DECLARE @datetime2 datetime2;
SET @datetime2 = '2007-01-01 01:01:01.1111111';
--Statement                                 Result   
-------------------------------------------------------------------                                   
SELECT DATEADD(quarter,4,@datetime2);     --2008-01-01 01:01:01.110
SELECT DATEADD(month,13,@datetime2);      --2008-02-01 01:01:01.110
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(day,365,@datetime2);       --2008-01-01 01:01:01.110
SELECT DATEADD(week,5,@datetime2);        --2007-02-05 01:01:01.110
SELECT DATEADD(weekday,31,@datetime2);    --2007-02-01 01:01:01.110
SELECT DATEADD(hour,23,@datetime2);       --2007-01-02 00:01:01.110
SELECT DATEADD(minute,59,@datetime2);     --2007-01-01 02:00:01.110
SELECT DATEADD(second,59,@datetime2);     --2007-01-01 01:02:00.110
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110

C. number パラメーターと date パラメーターの引数として式を使用する

次の例では、number パラメーターと date パラメーターの引数として各種の式を使用しています。

列を date として指定する

次の例では、各 OrderDate に 2 日を加算して、新しい PromisedShipDate を算出しています。

USE AdventureWorks;
GO
SELECT SalesOrderID
    ,OrderDate 
    ,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

number および date にユーザー定義変数を指定する

次の例では、number と date の引数としてユーザー定義変数を指定しています。

DECLARE @days int;
DECLARE @datetime datetime;
SET @days = 365;
SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */
SELECT DATEADD(day, @days, @datetime);

スカラー システム関数を date として指定する

次の例では、date に対して SYSDATETIME を指定しています。

SELECT DATEADD(month, 1, SYSDATETIME());

number および date にスカラー サブクエリやスカラー関数を指定する

次の例では、number と date の引数として、スカラー サブクエリおよびスカラー関数 (MAX(ModifiedDate)) を使用しています。number パラメーターに指定されている (SELECT TOP 1 ContactID FROM Person.Contact) は、値リストから number 引数を選択する方法を紹介するために用意した架空の引数です。

USE AdventureWorks;
GO
SELECT DATEADD(month,(SELECT TOP 1 ContactID FROM Person.Contact),
    (SELECT MAX(ModifiedDate) FROM Person.Contact));

number および date として定数を指定する

次の例では、number と date の引数として数値定数および文字定数を使用しています。

SELECT DATEADD(minute, 1, '2007-05-07 09:53:01.0376635');

number および date として数値式やスカラー システム関数を指定する

次の例では、number および date の引数として、数値式 (-(10/2))、単項演算子 (-)、算術演算子 (/)、およびスカラー システム関数 (SYSDATETIME) を使用しています。

SELECT DATEADD(month,-(10/2), SYSDATETIME());

number として順位付け関数を指定する

次の例では、number の引数として順位付け関数を使用しています。

USE AdventureWorks;
GO
SELECT c.FirstName, c.LastName
    ,DATEADD(day,ROW_NUMBER() OVER (ORDER BY
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s 
    INNER JOIN Person.Contact c 
        ON s.SalesPersonID = c.ContactID
    INNER JOIN Person.Address a 
        ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

number として集計関数を指定する

次の例では、number の引数として集計ウィンドウ関数を使用しています。

USE AdventureWorks;
GO
SELECT SalesOrderID, ProductID, OrderQty
    ,DATEADD(day,SUM(OrderQty) 
        OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);
GO

D. dmy 日付形式を使用するロケールで DATEADD を使用する

以下の例では、あるロケールで DATEADD と共に文字列リテラルを使用する方法を示します。

文字列リテラルの暗黙的なキャストを使用する場合の問題点を示す

次の例では、文字列リテラルが明示的にキャストされていない場合の動作を示します。

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0,'1987-03-07'));

SELECT DATENAME(m, '1987-03-07');

GO

最初の SELECT ステートメントは月の値として julio (July) を返し、2 番目の SELECT ステートメントは marzo (March) を返します。

文字列リテラルを明示的にキャストすることで誤った結果を回避する

次の例では、誤った結果が返されないように、date パラメーターを明示的にキャストする方法を示します。

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0, CAST('1987-03-07' AS datetime2)));

SELECT DATENAME(m, '1987-03-07');

GO

どちらの SELECT ステートメントも、月の値として marzo (March) を返します。

文字列リテラルの代わりに datetime2 変数を使用する

次の例では、文字列リテラルを直接使用しない方法を示します。

SET LANGUAGE Español;

GO

DECLARE @d datetime2 = '1987-03-07';

SELECT DATENAME(m, DATEADD(d, 0, @d));

SELECT DATENAME(m, @d);

GO