关于tsql:在SQL Server中设置日期

关于tsql:在SQL Server中设置日期

Floor a date in SQL server

在SQL Server中,如何将DATETIME"设置"到秒/分钟/小时/天/年?

假设我的日期为2008-09-17 12:56:53.430,那么flooring的输出应为:

  • 年份: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

关键是使用DATEADD和DATEDIFF以及适当的SQL时间跨度枚举。

1
2
3
4
5
6
7
8
9
10
11
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,通常会出现算术溢出。因此,请选择一个已知值,该值一定要小于您要底线的日期时间。


在SQL Server中,有一些技巧可以做到这一点:

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

您将DateTime转换为一个浮点数,该浮点数将Date表示为整数部分,并将Time表示为经过的一天的一部分。切掉该小数部分,然后将其转换回DateTime,那么您将在当天开始的午夜。

这可能比所有DATEADD和DATEDIFF东西更有效。这肯定是更容易键入的方式。


扩展转换/发布解决方案,在Microsoft SQL Server 2008中,您可以执行以下操作:

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

只需将getdate()替换为日期时间的任何列即可。

此转换不涉及任何字符串。

对于临时查询或更新,这是可以的,但是对于键联接或频繁使用的处理,最好在处理过程中处理转换或将表重新定义为具有适当的键和数据。

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

我也不认为它使用字符串转换,但是我不能说将实际效率与扶手椅估计进行比较。


多年来,我已经多次使用@Portman的答案作为地板日期的参考,并将其工作转移到您可能会发现有用的功能中。

我对它的性能不做任何声明,而只是将其作为工具提供给用户。

我要求,如果您决定赞成这个答案,请也赞成@Portman的答案,因为我的代码是他的衍生作品。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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

用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
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()方法,如此处所引用


DateAdd和DateDiff可以帮助完成许多不同的任务。例如,您可以找到任何月份的最后一天,也可以找到上个月或下个月的最后一天。

1
2
3
4
5
6
7
8
9
----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

资源


有几种方法可以给这只猫换皮=)

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

由于PostgreSQL也是" SQL Server",因此我将提及

1
date_trunc()

哪一个恰好符合您的要求。

例如:

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

推荐阅读

    linux输出结果命令?

    linux输出结果命令?,标准,工作,系统,信息,命令,文件,百度,数字,环境,设备,lin

    linux设置命令行长度?

    linux设置命令行长度?,系统,工作,信息,地址,命令,工具,异常,管理,目录,文件,l

    linux获取命令输出行?

    linux获取命令输出行?,数字,工具,系统,数据,命令,文件,内容,文本,尾部,表示,L

    linux输出字符串命令?

    linux输出字符串命令?,标准,基础,字符串,资料,简介,商业,数字,系统,命令,汉

    linux设置代替命令?

    linux设置代替命令?,系统,地址,网络,工作,软件,工具,服务,信息,命令,别名,lin

    linux命令设置时区?

    linux命令设置时区?,时间,系统,国家,大陆,命令,时区,时钟,日期,指令,时分,lin

    linux命令输出中文?

    linux命令输出中文?,系统,标的,底部,中文,命令,字符集,输入法,网络安全,级

    linux设置命令限制?

    linux设置命令限制?,数字,情况,信息,管理,系统,最新,在线,设备,第一,发行,Lin

    linux设置日志命令行?

    linux设置日志命令行?,异常,系统,实时,日志,管理,信息,对比,项目,名称,情况,L

    linux命令行设置网卡?

    linux命令行设置网卡?,系统,地址,信息,网络,工具,电脑,工作,名称,设备,网卡,l

    linux命令优先级设置?

    linux命令优先级设置?,系统,时间,实时,策略,优先级,分时,管理,周期性,进程,

    linux命令输出格式化?

    linux命令输出格式化?,电脑,系统,标准,位置,设备,图片,首次,管理,网络,命令,L

    linux设置ip命令?

    linux设置ip命令?,地址,系统,密码,设备,命令,服务,工具,网络,网卡,计算机,在L

    linux设置命令是什么?

    linux设置命令是什么?,系统,工作,信息,名称,地址,命令,在线,基础,标准,工具,l

    linux标准输出命令?

    linux标准输出命令?,标准,工作,系统,信息,地址,命令,环境,基础,设备,数字,lin

    linux命令设置密码?

    linux命令设置密码?,密码,系统,服务,软件,地址,电脑,流程,管理,用户,命令,问

    linux设置编码命令?

    linux设置编码命令?,系统,数据,发展,文件,字符集,命令,数据库,以下,终端,大

    linux常用输出命令?

    linux常用输出命令?,工作,系统,地址,管理,信息,标准,命令,目录,数据,位置,lin

    linux命令行设置语言?

    linux命令行设置语言?,系统,管理,环境,国家,工具,电脑,软件,文化,底部,语言,l

    linux设置壁纸的命令?

    linux设置壁纸的命令?,图片,系统,电脑,照片,位置,终端,颜色,字体,单击,壁纸,