代码之家  ›  专栏  ›  技术社区  ›  John Gietzen

在sql server中截短日期的最佳方法是什么?

  •  13
  • John Gietzen  · 技术社区  · 15 年前

    如果我的日期值是 2010-03-01 17:34:12.018

    最有效的方法是什么 2010-03-01 00:00:00.000 ?

    作为第二个问题,模仿甲骨文的最佳方法是什么? TRUNC 函数,它允许您截断年、季度、月、周、日、小时、分钟和第二个边界?

    4 回复  |  直到 8 年前
        1
  •  29
  •   Andomar    15 年前

    四舍五入 一整天 ,有三种方法被广泛使用。第一个使用 datediff 查找自 0 日期时间。这个 日期时间是1900年1月1日。在开始日期上加上日差,就可以四舍五入到一整天;

    select dateadd(d, 0, datediff(d, 0, getdate()))
    

    第二种方法是基于文本的:它用 varchar(10) ,只留下日期部分:

    select convert(varchar(10),getdate(),111)
    

    第三种方法使用的事实是 datetime 实际上是一个浮点数,表示自1900年以来的天数。所以把它四舍五入成一个整数,例如 floor ,您将获得一天的开始:

    select cast(floor(cast(getdate() as float)) as datetime)
    

    回答你的第二个问题 本周开始 更棘手。一种方法是减去星期几:

    select dateadd(dd, 1 - datepart(dw, getdate()), getdate())
    

    这也返回一个时间部分,因此您必须将其与一个时间剥离方法相结合才能到达第一个日期。例如,使用 @start_of_day 作为可读性的变量:

    declare @start_of_day datetime
    set @start_of_day = cast(floor(cast(getdate() as float)) as datetime)
    select dateadd(dd, 1 - datepart(dw, @start_of_day), @start_of_day)
    

    这个 年初、月、时、分 仍然使用“自1900年以来的差异”方法:

    select dateadd(yy, datediff(yy, 0, getdate()), 0)
    select dateadd(m, datediff(m, 0, getdate()), 0)
    select dateadd(hh, datediff(hh, 0, getdate()), 0)
    select dateadd(mi, datediff(mi, 0, getdate()), 0)
    

    按秒舍入 需要不同的方法,因为 使溢出。一种方法是使用一天的开始而不是1900作为参考日期:

    declare @start_of_day datetime
    set @start_of_day = cast(floor(cast(getdate() as float)) as datetime)
    select dateadd(s, datediff(s, @start_of_day, getdate()), @start_of_day)
    

    转5分钟 ,调整分钟取整方法。以微小差的商为例,使用 /5*5 :

    select dateadd(mi, datediff(mi,0,getdate())/5*5, 0)
    

    这也能工作四分之一个半小时。

        2
  •  15
  •   D'Arcy Rittich    15 年前

    如果使用的是SQL Server 2008,则可以使用新的 Date 数据类型如下:

    select cast(getdate() as date)
    

    如果你还需要你的价值 DateTime 数据类型,可以执行以下操作:

    select cast(cast(getdate() as date) as datetime)
    

    应在所有版本的SQL Server上工作的方法是:

    select cast(floor(cast(getdate() as float)) as datetime)
    
        3
  •  2
  •   Community Mohan Dere    8 年前

    尝试:

    SELECT DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)
    

    更新: 回答第二个问题: 多年来,你可以使用我的答案的一个小修改版本:

    SELECT DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)
    

    四分之一:

    SELECT DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)
    

    等等。

    我查过了,最多几分钟-没关系。但几秒钟后我收到一条溢出消息:

    两个日期时间列的差异 导致运行时溢出。

    另一个更新: 看看下面的答案 question

        4
  •  1
  •   Andrew    8 年前

    这是晚了,但将产生确切的结果要求在张贴。我也觉得它比使用dateadd更直观,但这是我的偏好。

    declare @SomeDate datetime = '2010-03-01 17:34:12.018'
    SELECT 
     DATEFROMPARTS(
         YEAR(@SomeDate)
        ,MONTH(@SomeDate)
        ,'01'
        ) AS CUR_DATE_FROM_PARTS
    ,DATETIMEFROMPARTS(
         YEAR(@SomeDate)                     
        ,MONTH(@SomeDate)                
        ,'01' --DAY(@SomeDate)                   
        ,'00' --DATEPART(HOUR,@SomeDate)         
        ,'00' --DATEPART(MINUTE,@SomeDate)       
        ,'00' --DATEPART(SECOND,@SomeDate)       
        ,'00' --DATEPART(MILLISECOND,@SomeDate) 
        ) AS CUR_DATETIME_FROM_PARTS
    ,@SomeDate                         AS CUR_DATETIME
    ,YEAR(@SomeDate)                   AS CUR_YEAR
    ,MONTH(@SomeDate)                  AS CUR_MONTH
    ,DAY(@SomeDate)                    AS CUR_DAY
    ,DATEPART(HOUR,@SomeDate)          AS CUR_HOUR
    ,DATEPART(MINUTE,@SomeDate)        AS CUR_MINUTE
    ,DATEPART(SECOND,@SomeDate)        AS CUR_SECOND
    ,DATEPART(MILLISECOND,@SomeDate)   AS CUR_MILLISECOND
    FROM Your_Table
    

    截短日期:2010-03-01

    截短日期时间:2010-03-01 00:00:00.000

    日期:2010-03-01 17:34:12.017