当前位置:  开发笔记 > 编程语言 > 正文

使用T-SQL从日期和年份创建日期

如何解决《使用T-SQL从日期和年份创建日期》经验,为你挑选了8个好方法。

我试图将日期与单个部分(如12,1,2007)转换为SQL Server 2005中的日期时间.我尝试了以下内容:

CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)

但这会导致错误的日期.将三个日期值转换为正确的日期时间格式的正确方法是什么.



1> Charles Bret..:

试试这个:

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)); 


@Brandon,你应该把它标记为这个答案.这是最好的一个.将其作为其他StackOverflow读取器的服务.
当传递无效的值组合时,例如`@Year = 2001`,`@Month = 13`和'@DayOfMonth = 32`导致有效但虚假的日期值导致`2002-02-01T00:00:00.000`.接受的答案(由Cade Roux提供)会产生错误,这更有用.
您不必从零开始并添加天数.您可以直接使用@ DayOfMonth-1开始,然后添加月份和年份.这比DateAdd()少了一个!
适用于闰年:选择dateadd(mm,(@ y-1900)*12 + @m - 1,0)+(@ d-1)
我的头还在旋转 - 真的没有更简洁的方法吗?(我的任务是在SQL Server 2005中修复查询)

2> Cade Roux..:

SQL Server 2012有一个很棒且期待已久的新DATEFROMPARTS函数(如果日期无效会引发错误 - 我主要反对基于DATEADD的解决这个问题的方法):

http://msdn.microsoft.com/en-us/library/hh213228.aspx

DATEFROMPARTS(ycolumn, mcolumn, dcolumn)

要么

DATEFROMPARTS(@y, @m, @d)


此外,参考原始问题,其中提到了Datetime对象,还有一个名为DATETIMEFROMPARTS的函数:https://msdn.microsoft.com/pl-pl/library/hh213233%28v=sql.110%29.aspx

3> Cade Roux..:

假设y, m, d都是int,怎么样:

CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)

请参阅SQL Server 2012及更高版本的其他答案


Oleg SQL Server DateTime不再往前走1753-01-01了.
此答案取决于日期格式设置,如果您未指定,则取决于服务器的区域设置.无论这些设置如何,`yyyymmdd`格式都有效."六位或八位数字符串总是被解释为*ymd*." https://docs.microsoft.com/en-us/sql/t-sql/data-types/date-transact-sql#ansi-and-iso-8601-compliance查看此答案:https://stackoverflow.com /一个/2266979分之46064419

4> 小智..:

或者只使用一个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)


最好的答案IMO.具有查尔斯答案的所有优点,并且更短.

5> Brian..:

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



6> devio..:

尝试CONVERT而不是CAST.

CONVERT允许第三个参数指示日期格式.

格式列表在这里:http://msdn.microsoft.com/en-us/library/ms187928.aspx

选择另一个答案后更新为"正确"答案:

我真的不明白为什么选择的答案显然取决于服务器上的NLS设置,而不指明此限制.



7> 小智..:

你也可以使用

select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3 
From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd

从ver.2012和AzureSQL开始在SQL中运行



8> Jack..:

使用明确的起点'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

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有