Порка мертвую лошадь на этом, но вот мое объяснение.
DATEADD(yy...
добавляет годы к указанной дате. (В стороне, сокращенные формы злы, вы должны использовать DATEADD(YEAR,...)
для ясности).
Дата 0
, как и все остальные, Полночь, понедельник, 1 января 1900 года. Дата -1
- воскресенье, 31 декабря 1899 года, за 1 день до этого.
Если добавить 116+1
к дате -1
Вы получаете 31 декабря, (1899 + 117) = 2016. Вы также можете написать это как SELECT DATEADD(YEAR,117, '1899-12-31')
или множество других способов с использованием даты литералов.
Bonus
Как почему он возвращает Datetime
в противоположность Datetime2
, а Smalldatetime
или любой другой тип, DATEADD
возвращает любой тип вы передаете в качестве параметра даты. -1
преобразуется неявно (согласно нормальным правилам литья/конвертации) в Datetime - см. https://msdn.microsoft.com/en-AU/library/ms187928.aspx.
Если вы хотите увидеть это в действии, этот код покажет вам результат кормления DATEADD
с различными типами:
SELECT
SQL_VARIANT_PROPERTY(GETDATE(), 'BaseType') BaseType,
SQL_VARIANT_PROPERTY(DATEADD(DAY, 1, GETDATE()), 'BaseType') DateAddBaseType,
SQL_VARIANT_PROPERTY(DATEADD(DAY, 1, CAST(GETDATE() AS DATETIME2)), 'BaseType') DateAddDatetime2,
SQL_VARIANT_PROPERTY(DATEADD(DAY, 1, CAST(GETDATE() AS SMALLDATETIME)), 'BaseType') DateAddSmallDatetime,
SQL_VARIANT_PROPERTY(DATEADD(DAY, 1, CONVERT(DATETIME2, GETDATE())), 'BaseType') DateAddDatetime2Convert
Extra Bonus
Если вы хотите, последний день текущий год:
SELECT DATEADD(DAY, -1, DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE())+1,0))
Или если вы хотите получить последнее разрешимое datetime2 текущего года (то есть 100 нс для е полночь день нового года):
SELECT DATEADD(NANOSECOND, -100,CAST(DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE())+1,0) AS DATETIME2(7)))
Изучение каждого из них, и, надеюсь, вы будете иметь возможность работать, что они делают.
Какую часть вы не понимаете, точно? Не могли бы вы подробнее рассказать об этом? –