Hun*_*eez -4 sql t-sql sql-server sql-server-2008
为什么这会给我一个DATETIME的结果?
Select DATEADD(yy,116, 0)
Run Code Online (Sandbox Code Playgroud)
输出:
2016-01-01 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
还有这个
Select DATEADD(yy,116 +1, -1)
Run Code Online (Sandbox Code Playgroud)
退还给我一年中的最后一天?
这背后的诀窍是什么?我只是玩它,但不知道它是怎么来的?
日期0
是1900-01-01
,
所以日期-1
是1899-12-31
IE(减少1天1900-01-01
)
SELECT CONVERT(datetime, 0) : Result is 1900-01-01 00:00:00.000
Run Code Online (Sandbox Code Playgroud)
因此Select DATEADD(yy,116 +1, -1)
将在1899年增加116 + 1(即117)年
(117 years will add to 1899-12-31 00:00:00.000
)
这是我的解释。
DATEADD(yy...
正在向给定日期添加年份。(顺便说一句,缩写形式是邪恶的,DATEADD(YEAR,...)
为了清晰起见,您应该使用缩写形式)。
0
正如其他人所说,日期是 1900 年 1 月 1 日星期一午夜。日期-1
是 1899 年 12 月 31 日星期日,前一天。
如果添加116+1
到 Date,-1
则会得到 12 月 31 日,(1899 + 117) = 2016。您还可以SELECT DATEADD(YEAR,117, '1899-12-31')
使用日期文字将其写为或多种其他方式。
奖金
至于为什么它返回 aDatetime
而不是 a Datetime2
、 aSmalldatetime
或任何其他类型,DATEADD
则返回您作为日期参数传递的任何类型。-1
隐式转换(按照正常的转换/转换规则)为日期时间 - 请参阅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
Run Code Online (Sandbox Code Playgroud)
额外奖励
如果您想要今年的最后一天:
SELECT DATEADD(DAY, -1, DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE())+1,0))
Run Code Online (Sandbox Code Playgroud)
或者,如果您想要当年的最后一个可解析的 datetime2 (即元旦午夜之前 100 纳秒):
SELECT DATEADD(NANOSECOND, -100,CAST(DATEADD(YEAR,DATEDIFF(YEAR,0,GETDATE())+1,0) AS DATETIME2(7)))
Run Code Online (Sandbox Code Playgroud)
检查每一个,希望您能够弄清楚它们在做什么。