DATEADD (Transact-SQL)
number に指定された間隔 (符号付き整数) を加算した date を返します。この間隔は、指定した date の datepart に加算されます。
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