我试图将日期与单个部分(如12,1,2007)转换为SQL Server 2005中的日期时间.我尝试了以下内容:
CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)
但这会导致错误的日期.将三个日期值转换为正确的日期时间格式的正确方法是什么.
试试这个:
Declare @DayOfMonth TinyInt Set @DayOfMonth = 13 Declare @Month TinyInt Set @Month = 6 Declare @Year Integer Set @Year = 2006 -- ------------------------------------ Select DateAdd(day, @DayOfMonth - 1, DateAdd(month, @Month - 1, DateAdd(Year, @Year-1900, 0)))
它也有效,增加了不进行任何字符串转换的好处,因此它是纯算术处理(非常快)并且它不依赖于任何日期格式这充分利用了SQL Server的datetime和smalldatetime值的内部表示是两个的事实part值的第一部分是一个整数,表示自1900年1月1日以来的天数,第二部分是一个小数部分,表示一天的小数部分(当时)---所以整数值0(零)总是直接翻译成1900年1月1日的午夜...
或者,感谢@brinary提出的建议,
Select DateAdd(yy, @Year-1900, DateAdd(m, @Month - 1, @DayOfMonth - 1))
2014年10月编辑.正如@cade Roux所述,SQL 2012现在有一个内置函数:
DATEFROMPARTS(year, month, day)
它做同样的事情.
2016年10月3日编辑,(感谢@bambams注意到这一点,以及@brinary修复它),最后的解决方案,由@brinary提出.除非首先进行多年添加,否则似乎不适用于闰年
select dateadd(month, @Month - 1, dateadd(year, @Year-1900, @DayOfMonth - 1));
SQL Server 2012有一个很棒且期待已久的新DATEFROMPARTS函数(如果日期无效会引发错误 - 我主要反对基于DATEADD的解决这个问题的方法):
http://msdn.microsoft.com/en-us/library/hh213228.aspx
DATEFROMPARTS(ycolumn, mcolumn, dcolumn)
要么
DATEFROMPARTS(@y, @m, @d)
假设y, m, d
都是int
,怎么样:
CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)
请参阅SQL Server 2012及更高版本的其他答案
或者只使用一个dateadd函数:
DECLARE @day int, @month int, @year int SELECT @day = 4, @month = 3, @year = 2011 SELECT dateadd(mm, (@year - 1900) * 12 + @month - 1 , @day - 1)
Sql Server 2012有一个函数,它将根据部分(DATEFROMPARTS)创建日期.对于我们其他人来说,这是我创建的一个db函数,它将从部件中确定日期(感谢@Charles)...
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[func_DateFromParts]')) DROP FUNCTION [dbo].[func_DateFromParts] GO CREATE FUNCTION [dbo].[func_DateFromParts] ( @Year INT, @Month INT, @DayOfMonth INT, @Hour INT = 0, -- based on 24 hour clock (add 12 for PM :) @Min INT = 0, @Sec INT = 0 ) RETURNS DATETIME AS BEGIN RETURN DATEADD(second, @Sec, DATEADD(minute, @Min, DATEADD(hour, @Hour, DATEADD(day, @DayOfMonth - 1, DATEADD(month, @Month - 1, DATEADD(Year, @Year-1900, 0)))))) END GO
你可以这样称呼它......
SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT)
返回...
2013-10-04 15:50:00.000
尝试CONVERT而不是CAST.
CONVERT允许第三个参数指示日期格式.
格式列表在这里:http://msdn.microsoft.com/en-us/library/ms187928.aspx
选择另一个答案后更新为"正确"答案:
我真的不明白为什么选择的答案显然取决于服务器上的NLS设置,而不指明此限制.
你也可以使用
select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3 From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd
从ver.2012和AzureSQL开始在SQL中运行
使用明确的起点'19000101'更安全更整洁
create function dbo.fnDateTime2FromParts(@Year int, @Month int, @Day int, @Hour int, @Minute int, @Second int, @Nanosecond int) returns datetime2 as begin -- Note! SQL Server 2012 includes datetime2fromparts() function declare @output datetime2 = '19000101' set @output = dateadd(year , @Year - 1900 , @output) set @output = dateadd(month , @Month - 1 , @output) set @output = dateadd(day , @Day - 1 , @output) set @output = dateadd(hour , @Hour , @output) set @output = dateadd(minute , @Minute , @output) set @output = dateadd(second , @Second , @output) set @output = dateadd(ns , @Nanosecond , @output) return @output end