在SQL服务器中放置一个date

在SQL Server中,如何“DATETIME”到第二/分钟/小时/天/年?

假设我有一个2008-09-17 12:56:53.430的date,那么地板的输出应该是:

  • 年份:2008-01-01 00:00:00.000
  • 月份:2008-09-01 00:00:00.000
  • date:2008-09-17 00:00:00.000
  • 小时:2008-09-17 12:00:00.000
  • 分钟:2008-09-17 12:56:00.000
  • 第二名:2008-09-17 12:56:53.000

关键是使用DATEADD和DATEDIFF以及相应的SQL时间范围枚举。

declare @datetime datetime; set @datetime = getdate(); select @datetime; select dateadd(year,datediff(year,0,@datetime),0); select dateadd(month,datediff(month,0,@datetime),0); select dateadd(day,datediff(day,0,@datetime),0); select dateadd(hour,datediff(hour,0,@datetime),0); select dateadd(minute,datediff(minute,0,@datetime),0); select dateadd(second,datediff(second,'2000-01-01',@datetime),'2000-01-01'); 

请注意,当您第二次铺地时,如果使用0,则经常会发生算术溢出。因此,请select一个已知值,该值确保低于您尝试铺设的date。

在SQL Server中,这是一个小技巧:

 SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME) 

您将DateTime转换为一个浮点数,该浮点数表示Date作为整数部分,Time表示通过一天的分数。 剔掉这个小数部分,然后把它转换回date时间,并且在那天开始的时候你已经有午夜了。

这可能比所有的DATEADD和DATEDIFF的东西更有效率。 打字肯定是比较容易的。

在Microsoft SQL Server 2008中扩展Convert / Cast解决scheme,您可以执行以下操作:

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

只需将getdate()replace为date时间的任何列即可。

这个转换中没有string。

这对于即席查询或更新是可以的,但是对于键连接或重度使用的处理,在处理内处理转换或者重新定义表格以具有适当的键和数据可能更好。

在2005年,你可以使用messier地板: cast(floor(cast(getdate() as float)) as datetime)

我不认为也使用string转换,但我不能说比较实际的效率和扶手椅的估计。

多年来,我一直使用@波特曼的答案作为地板date的参考,并将其工作转移到您可能认为有用的function上。

我没有声称它的performance,只是作为一个工具提供给用户。

我问,如果你决定高调回答这个问题,也请提出@波特曼的回答 ,因为我的代码是他的一个衍生物。

 IF OBJECT_ID('fn_FloorDate') IS NOT NULL DROP FUNCTION fn_FloorDate SET ANSI_NULLS OFF GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[fn_FloorDate] ( @Date DATETIME = NULL, @DatePart VARCHAR(6) = 'day' ) RETURNS DATETIME AS BEGIN IF (@Date IS NULL) SET @Date = GETDATE(); RETURN CASE WHEN LOWER(@DatePart) = 'year' THEN DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0) WHEN LOWER(@DatePart) = 'month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0) WHEN LOWER(@DatePart) = 'day' THEN DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0) WHEN LOWER(@DatePart) = 'hour' THEN DATEADD(HOUR, DATEDIFF(HOUR, 0, @Date), 0) WHEN LOWER(@DatePart) = 'minute' THEN DATEADD(MINUTE, DATEDIFF(MINUTE, 0, @Date), 0) WHEN LOWER(@DatePart) = 'second' THEN DATEADD(SECOND, DATEDIFF(SECOND, '2000-01-01', @Date), '2000-01-01') ELSE DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0) END; END 

用法:

 DECLARE @date DATETIME; SET @date = '2008-09-17 12:56:53.430'; SELECT @date AS [Now],--2008-09-17 12:56:53.430 dbo.fn_FloorDate(@date, 'year') AS [Year],--2008-01-01 00:00:00.000 dbo.fn_FloorDate(default, default) AS [NoParams],--2013-11-05 00:00:00.000 dbo.fn_FloorDate(@date, default) AS [ShouldBeDay],--2008-09-17 00:00:00.000 dbo.fn_FloorDate(@date, 'month') AS [Month],--2008-09-01 00:00:00.000 dbo.fn_FloorDate(@date, 'day') AS [Day],--2008-09-17 00:00:00.000 dbo.fn_FloorDate(@date, 'hour') AS [Hour],--2008-09-17 12:00:00.000 dbo.fn_FloorDate(@date, 'minute') AS [Minute],--2008-09-17 12:56:00.000 dbo.fn_FloorDate(@date, 'second') AS [Second];--2008-09-17 12:56:53.000 

CONVERT()函数也可以这样做,这取决于你使用的风格。

太糟糕了不是Oracle,否则你可以使用trunc()或to_char()。

但是我遇到过与SQL Server类似的问题,并使用CONVERT()和DateDiff()方法,如下所示

有几种方法来剥皮这只猫=)

 select convert(datetime,convert(varchar,CURRENT_TIMESTAMP,101)) 

DateAdd和DateDiff可以帮助完成许多不同的任务。 例如,你可以find任何月份的最后一天,以及可以find前一个或下个月的最后一天。

 ----Last Day of Previous Month SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)) LastDay_PreviousMonth ----Last Day of Current Month SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)) LastDay_CurrentMonth ----Last Day of Next Month SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)) LastDay_NextMonth 

资源

由于PostgreSQL也是一个“SQL Server”,我会提到的

 date_trunc() 

这正是你正在优雅地问。

例如:

 selectdate_trunc('hour',current_timestamp);
        date_trunc
 ------------------------
  2009-02-18 07:00:00-08
 (1排)