在SQL服务器中发布日期

问题描述:

在SQL Server中,如何将DATETIME“发布”到第二/分钟/小时/天/年?在SQL服务器中发布日期

比方说,我有2008-09-17 12日期:56:53.430,则地板的输出应该是:

  • 年份:2008-01-01 00:00: 00.000
  • 月份:2008-09-01 00:00:00.000
  • 日: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

的关键是使用DATEADDDATEDIFF与适当的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'); 
select dateadd(week,datediff(week,0,@datetime),-1); --Beginning of week is Sunday 
select dateadd(week,datediff(week,0,@datetime),0); --Beginning of week is Monday 

注意,当你在地板第二,你会经常如果使用0,所以挑选这是保证比你试图地板的日期时间下一个已知值获取算术溢出。

+1

你计算从不需要为过去的偏移的日期。任何日期都可以工作,只要它自己'在问题的时间间隔FLOOR'。如果基准日期在将来,则只会得到一个负的偏移值... – MatBailie 2009-10-06 16:20:34

+0

如果星期几是星期几的第一天,则使用此参数... select dateadd(week,datediff(week,0, @datetime), - 1) – 2013-07-12 18:30:34

+0

如果星期一是一周中的第一天,则使用此选项... select dateadd(week,datediff(week,0,@ datetime),0) – 2013-07-12 18:33:44

CONVERT()函数也可以做到这一点,这取决于你使用的是什么风格。

+2

我们发现CONVERT()可以比dateadd/datediff低10%到5倍的性能。 SQL对数字类型和字符串之间的转换施加了一个惩罚,然后再返回。 – Portman 2008-09-17 19:32:10

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

但我不得不与SQL Server类似的问题和所使用的CONVERT()和则DateDiff()方法,如引用here

在SQL Server这里有一个小窍门要做到这一点:

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

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

这可能比所有的DATEADD和DATEDIFF的东西更有效。这当然更容易打字。

因为PostgreSQL也是“SQL服务器”,我会提到

date_trunc() 

哪些呢你问什么优雅。

例如:

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

扩大在转换/施放的解决方案,在Microsoft SQL Server 2008中,你可以做到以下几点:

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

只是这是一个日期时间任何替换列getdate()

此转换中没有字符串参与。

这适用于临时查询或更新,但对于键连接或重度使用的处理,处理处理内的转换或重新定义表以获得适当的键和数据可能更好。

在2005年,您可以使用混乱地板:cast(floor(cast(getdate() as float)) as datetime)

我不认为使用字符串转换下去,但我无法比较实际的效率与扶手椅估计说话。

多年来我多次使用@Portman's answer作为地板日期的参考,并将其工作转移到您可能会觉得有用的功能中。

我对其性能没有任何要求,只是将它作为用户的工具提供。

我问,如果你决定upvote这个答案,请upvote @Portman's answer,因为我的代码是他的衍生物。

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 

有几种方法对皮肤这只猫=)与沿则DateDiff

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

使用DateAdd可以帮助做很多不同的任务。例如,你可以找到任何月份的最后一天,以及可以找到上个月或下个月的最后一天。

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

Source