问题434378 br />

评论

如果您希望获取不带时间的日期数据类型,即使时间为00:00:00,那么您也很不走运,您可以获取varchar,但结构为datetime,因此您将始终有一些时间。 br />
需要注意的一件事是,SQL Server 2008包含一个单独的DATE数据类型,用于仅存储日期而没有时间成分。此处的更多信息:sql-server-performance.com/articles/dev/datetime_2008_p1.aspx

不要错过这篇显示各种省时方法的性能测试结果的帖子。

不要被投票和接受的答案误导,请看一下stackoverflow.com/a/126984/1155650

@Rohit您错误地认为2008是人们唯一关心的版本。 (在野外还有更多版本。)选票不言自明。

#1 楼

SQL Server 2008及更高版本上,您应该迄今使用CONVERT: >
例如

SELECT CONVERT(date, getdate())


给我

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))




不需要varchar <->需要datetime转换
无需考虑locale




如迈克尔

使用以下变体:SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

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


输出:

2008-09-22 00:00:00.000


评论


+1看起来这比常用的double convert()方法快35%(我也已经使用了多年)。好一个。

–丹麦人
08-09-22在4:04

我可以看到您的解决方案的唯一缺点是,除非您知道它在做什么,否则它会有些晦涩。使用double convert方法可使您的意图对于futire代码维护者更加明显。顺便说一句,我还没有打败你。我想我也会开始使用您的方法。谢谢@aku

– Jim Birchall
08年9月24日在8:25

@pilavdzice将日期时间设置为该日的午夜会离开该时间。您期待什么结果? datetime数据类型不能完全没有时间。我认为您将数据存储与用户演示混淆了。如果您只想向用户显示一个没有时间部分的字符串(不是零,只有空格),那么您只需要Convert(varchar(30),@Date,101)或类似的东西。有关更多信息,请参见SQL Server联机丛书•转换和转换。

– ErikE
2012年8月17日在22:03



@ user1671639 datetime数据类型始终包含日期和时间,您不能明智地存储日期和时间-除非您使用的是SQL Server 2008,否则还存在单独的“日期”和“时间”数据类型。如果您这样使用CONVERT(),则确实需要一个字符串供以后使用,因此您将不得不这样做-尽管使用日期格式函数而不是缩短日期会更好-或CAST(... AS DATE)或CONVERT(DATE,...),在此页面上经常提到。

–马格努斯
13年6月21日在15:08

我建议将答案更改为SELECT DATEADD(dd,DATEDIFF(dd,0,@your_date),0),因为这样dd可以换成任何其他datepart关键字以在任意级别截断日期时间。

–迈克尔
14年8月14日在16:08

#2 楼

SQLServer 2008现在具有“日期”数据类型,该数据类型仅包含没有时间成分的日期。使用SQLServer 2008及更高版本的任何人都可以执行以下操作:

SELECT CONVERT(date, GETDATE())


评论


SQL2008中还有一个“时间”数据类型,可以回答日期和时间分隔问题的另一半。

–misteraidan
11年8月25日在0:01

仅供参考,我以基准日期减少时间的不同方法作为基准,这是最快的方法。当然,差异很小,但显然在执行大量命令时,速度更快。

–UnhandledExcepSean
2014年7月3日,12:48

wt关于sqlserver 2005?

– MAF博士
2015年11月19日在9:10

@ Dr.MAF完成这一圈,2008年前的答案在这里:stackoverflow.com/questions/113045/…

–Frosty840
17年7月31日在7:24

#3 楼

如果使用SQL 2008及更高版本:

select cast(getdate() as date)


评论


@FredrickGauss:什么类型,日期?您使用什么版本的SQL Server?

– abatishchev
2012年12月13日在20:01

谨防!声明@ date1 datetime ='2015-09-30 20:59:59.999';选择演员(@ date1作为日期)返回'2015-10-01'

–尼克
2015年9月24日19:18在

@Nick:这是DateTime的问题。使用DateTime2代替,它工作正常。 sqlfiddle.com/#!6/9eecb7/2833

– abatishchev
2015年9月25日,下午1:33

@Nick,为补充abatishchev响应,由于DateTime的限制,您的@ date1确实为2015-10-01。尝试不进行任何迄今为止的转换,它会产生2015-10-01的错误!声明@ date1 datetime ='2015-09-30 23:59:59.999';选择@ date1 => 2015-10-01

–Frédéric
2015年12月11日在17:07

这些容易记住的SQL技巧之一。正如Mike所说,只有2008年以后,但是,如果您在某个地方找到了2005年和以前的DB,则可能会有很多问题:)

– NicVerAZ
15年12月29日在17:04

#4 楼

DATEADD和DATEDIFF优于转换为varchar。这两个查询具有相同的执行计划,但是执行计划主要是关于数据访问策略的,并不总是显示执行所有步骤所花费的CPU时间所隐含的成本。如果两个查询都针对具有数百万行的表运行,则使用DateDiff的CPU时间可能接近“转换CPU时间”的1/3!

要查看查询的执行计划:

set showplan_text on
GO 


DATEADD和DATEDIFF都将执行CONVERT_IMPLICIT。

尽管CONVERT解决方案更简单易读,但速度较慢。无需回退到日期时间(这是由服务器隐式完成的)。之后,DateAdd的DateDiff方法也没有真正的需求,因为整数结果也将隐式转换回datetime。


SELECT CONVERT(varchar,MyDate,101)FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))



从DatesTable中选择DATEADD(dd,0,DATEDIFF(dd,0,MyDate))

  |--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))


将FLOOR()用作@digi时,其性能接近于DateDiff,但不建议将其转换为float和back并不会始终产生原始值。伙计们:不要相信任何人。查看性能统计信息,然后自己进行测试!

在测试结果时请务必小心。选择许多行给客户端将隐藏性能差异,因为通过网络发送行比执行计算花费的时间更长。因此,请确保所有行的工作都由服务器完成,但没有行集发送给客户端。

对于缓存优化何时会影响查询,有些人似乎感到困惑。在同一批次或不同批次中运行两个查询对缓存没有影响。因此,您既可以手动使缓存过期,也可以简单地多次运行查询。查询2的任何优化都会影响后续查询,因此,如果您愿意,则放弃执行1。

评论


里卡多C,很好的调查!您使用什么版本的SQL Server?在带有datediff的MSSQL2000方法上,对我来说执行速度稍快。

–aku
08年9月24日在5:29

请注意,我执行了1000.000次测试。我想对于现实场景而言,性能差异不会很明显

–aku
08年9月24日在5:30

Aku,我为此测试使用了SQL Server 2005 Express。我使用2000进行工作,我将使用一个超过2400万行的表对其进行测试,然后看看会产生什么结果。

–里卡多C
08年9月24日在6:20

Aku,相同的结果。超过一千万行的性能没有差异。

–里卡多C
08-09-25 at 3:41

关于均等性能的主张是不正确的。当然执行计划是一样的!!!必须通过比较CPU使用率而不是检查执行计划来衡量这些服务器的性能。

– ErikE
2010-09-12 23:01

#5 楼

试试这个:

评论


这将为我返回“ 2008/09/22”

– eddiegroves
08-09-22在3:41

SELECT CONVERT(VARCHAR(10),GETDATE(),101)是mm / dd / yyyy格式。

–跳蚤
13年7月10日在20:47

如果您基于原始文本值(数据库外部)进行排序,则“日语”格式更好

–Simon_Weaver
2013年9月14日下午0:34

#6 楼

SELECT CONVERT(datetime, CONVERT(varchar, GETDATE(), 101))


#7 楼

对于以日期格式返回


CAST(OrderDate AS日期)


以上代码将在sql server 2010中工作

/>它会像2013年12月12日返回

对于SQL Server 2012,请使用以下代码

CONVERT(VARCHAR(10), OrderDate , 111)


评论


这会返回零时间的日期,而不仅仅是日期

–波西米亚风格♦
2014年1月5日13:09

我能知道您使用的是哪个版本的sql server?

–马赫什ML
2014年3月19日在7:15

@MaheshML它在MS SQL 2012中返回日期和时间。

–马雷克
14年4月13日在15:50

在SQL Azure中像魅力一样工作

–马丁·科尔(MartínColl)
2014年5月21日15:01

@MaheshML没有像SQL Server 2010这样的东西。

– SvenAelterman
17/09/25在2:22

#8 楼

您可以使用CONVERT函数仅返回日期。请参见下面的链接:

SQL Server 2000中的日期和时间处理

CAST和CONVERT

使用convert函数的语法是:

CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) 


#9 楼

如果您需要将结果作为varchar,则应通过上面已经提到的

SELECT CONVERT(DATE, GETDATE()) --2014-03-26
SELECT CONVERT(VARCHAR(10), GETDATE(), 111) --2014/03/26




如果需要日期中的结果和时间格式,则应使用以下任意查询



SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 111)) AS OnlyDate 



2014-03-26 00:00: 00.000



SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 112)) AS OnlyDate 



2014-03-26 00:00:00.000


/>
DECLARE  @OnlyDate DATETIME
SET @OnlyDate = DATEDIFF(DD, 0, GETDATE())
SELECT @OnlyDate AS OnlyDate



2014-03-26 00:00:00.000




#10 楼

如果您使用的是SQL Server 2012或更高版本,请使用Format()函数。

SQL Server已经存在多种答案和格式设置。
但是大多数方法都有些模棱两可,您将很难记住特定日期格式的格式类型或函数编号。这就是为什么在SQL Server的下一版本中会有更好的选择。

FORMAT ( value, format [, culture ] )


文化选项非常有用,因为您可以根据查看者指定日期。
您必须记住d(小图案)和D(长图案)。

1.“ d”-短日期图案。

2009-06-15T13:45:30 -> 6/15/2009 (en-US)
2009-06-15T13:45:30 -> 15/06/2009 (fr-FR)
2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)


2.“ D”-长日期模式。

2009-06-15T13:45:30 -> Monday, June 15, 2009 (en-US)
2009-06-15T13:45:30 -> 15 июня 2009 г. (ru-RU)
2009-06-15T13:45:30 -> Montag, 15. Juni 2009 (de-DE)


更多查询示例。

DECLARE @d DATETIME = '10/01/2011';
SELECT FORMAT ( @d, 'd', 'en-US' ) AS 'US English Result'
      ,FORMAT ( @d, 'd', 'en-gb' ) AS 'Great Britain English Result'
      ,FORMAT ( @d, 'd', 'de-de' ) AS 'German Result'
      ,FORMAT ( @d, 'd', 'zh-cn' ) AS 'Simplified Chinese (PRC) Result'; 

SELECT FORMAT ( @d, 'D', 'en-US' ) AS 'US English Result'
      ,FORMAT ( @d, 'D', 'en-gb' ) AS 'Great Britain English Result'
      ,FORMAT ( @d, 'D', 'de-de' ) AS 'German Result'
      ,FORMAT ( @d, 'D', 'zh-cn' ) AS 'Chinese (Simplified PRC) Result';

US English Result Great Britain English Result  German Result Simplified Chinese (PRC) Result
----------------  ----------------------------- ------------- -------------------------------------
10/1/2011         01/10/2011                    01.10.2011    2011/10/1

US English Result            Great Britain English Result  German Result                    Chinese (Simplified PRC) Result
---------------------------- ----------------------------- -----------------------------  ---------------------------------------
Saturday, October 01, 2011   01 October 2011               Samstag, 1. Oktober 2011        2011年10月1日


如果需要更多格式,可以转到:


标准日期和时间格式字符串
自定义日期和时间格式字符串


#11 楼

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),103) --21/09/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),101) --09/21/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),111) --2011/09/21

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),107) --Sep 21, 2011


#12 楼

使用FLOOR()-仅剪切时间部分。

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)


评论


这种方法不是最快的方法,并且还隐含地告诉人们,将日期转换为浮点数是准确的,但事实并非如此。请参阅此帖子以获取更多详细信息。

– ErikE
2010-09-12 23:16

#13 楼

如果您要使用CONVERT并获得与原始问题相同的输出,即yyyy-mm-dd,则使用与前面的几个答案相同的代码CONVERT(varchar(10),[SourceDate as dateTime],121),但该代码要用破折号转换为yyyy-mm-dd是121。

如果我可以稍等一会儿,这种格式就不属于数据层,这就是为什么没有愚蠢的高开销的技巧是不可能的直到引入实际datepart数据类型的SQL Server 2008。在数据层中进行此类转换会极大地浪费DBMS的开销,但是更重要的是,第二次执行类似的操作之后,您基本上已经创建了内存中孤立的数据,我认为您将随后返回程序。您不能将其放回另一个3NF +列中,也不能将其与任何类型的内容进行比较而不进行还原,因此,您所做的只是引入了故障点并删除了关系引用。

您应该始终继续并将dateTime数据类型返回给调用程序,并在PRESENTATION层中进行必要的调整。在将事物返回给调用者之前先进行转换,就从应用程序中消除了所有引用完整性的希望。除非您进行某种手动还原,否则这将再次阻止UPDATE或DELETE操作,这又在不需要时将数据暴露于人为/代码/ gremlin错误。

评论


除非,例如,如果要查询检索与用户提供的日期匹配的所有记录作为某个时间字段的日期部分。祝您好运,只有在表示层才能做到这一点。 (您不需要转换,可以使用日期算术,但是您知道了…)

–安德鲁·拉撒路(Andrew Lazarus)
13年3月14日在16:42

@Andrew为什么这么重要?您说WHERE col> = @Date AND col
–亚伦·伯特兰(Aaron Bertrand)
13年11月16日下午5:09

@AaronBertrand仅在输入@Date具有零时间部分的情况下起作用。如果情况并非如此,您仍然需要知道如何在服务器端截断时间。我同意这个答案,即格式化应该留给表示层,但我不同意暗示将其留在前端意味着您不必知道快速的截断方法。

–安德鲁·拉撒路(Andrew Lazarus)
13年11月16日在17:04

@Andrew您所要做的就是将输入参数设置为DATE。我的观点仍然是,即使那是大多数人的本能,您也不必将任何此类截断应用于该列。

–亚伦·伯特兰(Aaron Bertrand)
13年11月16日在20:25

@AaronBertrand,并假定您可以控制参数的数据类型。在存储过程中很好,在其他情况下则不太可能。为什么不进行强制转换以确保参数是您想要和需要的类型?

–安德鲁·拉撒路(Andrew Lazarus)
13年11月18日在23:42

#14 楼

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

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

SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 101))


编辑:前两个方法本质上是相同的,然后执行Convert to varchar方法。

评论


这些方法都很不错,但是您建议使用哪个方法呢?

– eddiegroves
08-09-22在3:48

请注意,前两个的“正确”版本是选择dateadd(dd,datediff(dd,0,getdate()),0),因为随后可以将dds换成任何datepart关键字以将日期剪裁为您选择的任何细分。 (还请注意,dd只是day的缩写。)

–迈克尔
14年8月14日在16:02

#15 楼

要获得指示的结果,请使用以下命令。

SELECT CONVERT(DATETIME,CONVERT(DATE,GETDATE()))


我希望它很有用。

#16 楼

 Convert(nvarchar(10), getdate(), 101) --->  5/12/14

 Convert(nvarchar(12), getdate(), 101) --->  5/12/2014


#17 楼

如果要将结果分配给列或变量,请为其指定DATE类型,并且转换是隐式的。

DECLARE @Date DATE = GETDATE()   

SELECT @Date   --> 2017-05-03


#18 楼

我认为这可以解决您的问题:

CONVERT(VARCHAR(10),Person.DateOfBirth,111) AS BirthDate
//here date is obtained as 1990/09/25


#19 楼

DECLARE @yourdate DATETIME = '11/1/2014 12:25pm'    
SELECT CONVERT(DATE, @yourdate)


评论


此建议已被其他答案覆盖(不止一次)。

– Andriy M
2014年11月19日在21:47

#20 楼

好的,虽然我来晚了:),这是另一种解决方案。

/>如果您使用的是SQL Server 2012和更高版本,则可以使用FORMAT()函数--

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) as DATETIME)


评论


您的第一个示例仍然具有时间成分。问题的关键是如何删除它。

–扎克
16年4月20日在21:20

#21 楼

日期:

SELECT CONVERT(date, GETDATE())
SELECT CAST(GETDATE() as date)


时间:

SELECT CONVERT(time , GETDATE() , 114)
SELECT CAST(GETDATE() as time)


#22 楼

即使使用古老的MSSQL Server 7.0,此处的代码(此链接提供)也允许我获取当时所需的日期格式:

PRINT '1) Date/time in format MON DD YYYY HH:MI AM (OR PM): ' + CONVERT(CHAR(19),GETDATE())  
PRINT '2) Date/time in format MM-DD-YY: ' + CONVERT(CHAR(8),GETDATE(),10)  
PRINT '3) Date/time in format MM-DD-YYYY: ' + CONVERT(CHAR(10),GETDATE(),110) 
PRINT '4) Date/time in format DD MON YYYY: ' + CONVERT(CHAR(11),GETDATE(),106)
PRINT '5) Date/time in format DD MON YY: ' + CONVERT(CHAR(9),GETDATE(),6) 
PRINT '6) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H): ' + CONVERT(CHAR(24),GETDATE(),113)


它产生了以下输出:

1) Date/time in format MON DD YYYY HH:MI AM (OR PM): Feb 27 2015  1:14PM
2) Date/time in format MM-DD-YY: 02-27-15
3) Date/time in format MM-DD-YYYY: 02-27-2015
4) Date/time in format DD MON YYYY: 27 Feb 2015
5) Date/time in format DD MON YY: 27 Feb 15
6) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H): 27 Feb 2015 13:14:46:630


#23 楼

只需执行以下操作即可:

SELECT CONVERT(date, getdate())
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))


输出为:

2008-09-22 00:00:00.000


结果:

SELECT CONVERT (DATE, GETDATE()) 'Date Part Only'


#24 楼

在这种情况下,只有日期,您将运行以下查询:

SELECT CONVERT(VARCHAR(10),getdate(),111);

#25 楼

为什么不使用DATE_FORMAT(your_datetiem_column,'%d-%m-%Y')?

EX:select DATE_FORMAT( some_datetime_column, '%d-%m-%Y' ) from table_name

您可以更改m,d和重新布置Q4312079Q零件的年份

#26 楼

我知道这很老,但是我看不到有人这样说。据我所知,这是ANSI标准。

评论


选择{fn current_date()},因为今天对我有用。

–brianary
19/12/2在18:26

@brianary-很好,但是不是ANSI SQL。

–点亮
19年12月8日在17:28

这很公平,而且您的答案很容易移植,但是我认为只要我们围绕T-SQL进行工作,它就也可以工作(并表明对于MS而言,实现ANSI CURRENT_DATE很简单)。

–brianary
19/12/8在18:28

#27 楼

我赞成以下未提及的内容:

DATEFROMPARTS(DATEPART(yyyy, @mydatetime), DATEPART(mm, @mydatetime), DATEPART(dd, @mydatetime))


它也不在乎本地或进行双转换-尽管每个'datepart'可能都在做数学运算。因此,它可能比datediff方法要慢一些,但是对我来说,它要清晰得多。特别是当我只想按年和月分组(将日期设置为1)时。

#28 楼

从SQL SERVER 2012开始,您可以执行以下操作:

SELECT FORMAT(GETDATE(), 'yyyy-MM-dd 00:00:00.000')

#29 楼

在SQL Server 2000上

CAST(
(
    STR( YEAR( GETDATE() ) ) + '/' +
    STR( MONTH( GETDATE() ) ) + '/' +
    STR( DAY( GETDATE() ) )
)
AS DATETIME)


#30 楼

只需执行:

SELECT CAST(date_variable AS date)

或与PostgreSQL一起使用:

SELECT date_variable::date