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 型を返します。DATEADD の date パラメーターに文字列リテラルを使用した場合、戻り値として 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 AdventureWorks2008R2;
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 BusinessEntityID FROM Person.Person) は、値リストから number 引数を選択する方法を紹介するために用意した架空の引数です。

USE AdventureWorks2008R2;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person));

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 AdventureWorks2008R2;
GO
SELECT p.FirstName, p.LastName
    ,DATEADD(day,ROW_NUMBER() OVER (ORDER BY
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson AS s 
    INNER JOIN Person.Person AS p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address AS a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

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

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

USE AdventureWorks2008R2;
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