当前位置:  开发笔记 > 数据库 > 正文

SQL Server中最有效的方法是从日期+时间获取日期?

如何解决《SQLServer中最有效的方法是从日期+时间获取日期?》经验,为你挑选了4个好方法。

在MS SQL 2000和2005中,给定日期时间,例如'2008-09-25 12:34:56',获得仅包含'2008-09-25'的日期时间的最有效方法是什么?

这里重复一遍.



1> Tomas..:

我必须承认我之前没见过马特所展示的地板浮动转换.我不得不测试一下.

我测试了一个纯粹的选择(它将返回日期和时间,而不是我们想要的),这里的统治解决方案(floor-float),这里提到的常见'天真'(stringconvert)和这里提到的那个我是使用(因为我认为它是最快的).

我测试了运行在Win 2003 SP2服务器上的测试服务器MS SQL Server 2005上的查询,其中Xeon 3GHz CPU在最大内存(32位,大约3.5 Gb)上运行.现在是我的所在地,所以机器几乎没有负载就在空转.我已经把它全部都给了自己.

这是我的测试运行中的日志,从包含时间戳变化到毫秒级别的大型表中进行选择.该特定数据集包括超过2.5年的日期.该表本身有超过1.3亿行,所以这就是我限制在百万之前的原因.

SELECT TOP 1000000 CRETS FROM tblMeasureLogv2 
SELECT TOP 1000000 CAST(FLOOR(CAST(CRETS AS FLOAT)) AS DATETIME) FROM tblMeasureLogv2
SELECT TOP 1000000 CONVERT(DATETIME, CONVERT(VARCHAR(10), CRETS, 120) , 120) FROM tblMeasureLogv2 
SELECT TOP 1000000 DATEADD(DAY, DATEDIFF(DAY, 0, CRETS), 0) FROM tblMeasureLogv2

SQL Server解析和编译时间:CPU时间= 0 ms,经过时间= 1 ms.

(1000000行受影响)表'tblMeasureLogv2'.扫描计数1,逻辑读取4752,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:CPU时间= 422毫秒,已用时间= 33803毫秒.

(1000000行受影响)表'tblMeasureLogv2'.扫描计数1,逻辑读取4752,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:CPU时间= 625毫秒,已用时间= 33545毫秒.

(1000000行受影响)表'tblMeasureLogv2'.扫描计数1,逻辑读取4752,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:CPU时间= 1953毫秒,已用时间= 33843毫秒.

(1000000行受影响)表'tblMeasureLogv2'.扫描计数1,逻辑读取4752,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.

SQL Server执行时间:CPU时间= 531 ms,已用时间= 33440 ms.SQL Server解析和编译时间:CPU时间= 0 ms,经过时间= 1 ms.

SQL Server执行时间:CPU时间= 0 ms,已用时间= 1 ms.

我们在这看到什么?

让我们关注CPU时间(我们正在考虑转换),我们可以看到我们有以下数字:

Pure-Select:  422
Floor-cast:   625
String-conv: 1953
DateAdd:      531  

从这一点来看,我认为DateAdd(至少在这种特殊情况下)比Floor-cast方法略快.

在你去那里之前,我多次运行这个测试,查询的顺序发生了变化,同样的结果.

我的服务器上有什么奇怪的东西,或者是什么?


这一点都不奇怪.首先,在我看来,转换为浮动是不好的做法,因为到达日期时间的往返转换是不可靠的.其次,请参阅[这篇文章,对各种方法进行更多性能测试](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a -datetime值-SQL服务器/ 3696991#3696991).

2> G Mastros..:
Select DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)

DateDiff(Day,0,GetDate())与DateDiff(Day,'1900-01-01',GetDate())相同

由于DateDiff返回一个整数,您将获得自1900年1月1日以来经过的天数.然后将该整数天添加到1900年1月1日.净效果是删除时间组件.

我还应该提一下,这种方法适用于任何日期/时间部分(如年,季,月,日,小时,分钟和秒).

Select  DateAdd(Year, DateDiff(Year, 0, GetDate()), 0)
Select  DateAdd(Quarter, DateDiff(Quarter, 0, GetDate()), 0)
Select  DateAdd(Month, DateDiff(Month, 0, GetDate()), 0)
Select  DateAdd(Day, DateDiff(Day, 0, GetDate()), 0)
Select  DateAdd(Hour, DateDiff(Hour, 0, GetDate()), 0)
Select  DateAdd(Second, DateDiff(Second, '20000101', GetDate()), '20000101')

最后一秒,需要特殊处理.如果您使用1900年1月1日,您将收到错误.

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

您可以使用不同的参考日期(如2000年1月1日)来规避此错误.


@Dar在我看来转换为浮动是不好的做法,因为往返于datetime的往返转换是不可靠的.请参阅[此帖更多详细信息](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-服务器/ 3696991#3696991).

3> Matt Howells..:
select cast(floor(cast(@datetime as float)) as datetime)

之所以有效,因为将日期时间转换为浮点数会给出自1900年1月1日以来的天数(包括一天的分数).地板会删除小数天并留下整天的天数,然后可以将其转换回日期时间.


SQL2008具有大大改进(并且非常需要)的日期处理功能.这就像将日期时间转换为新的日期类型一样简单.
@kristof datetime不是物理存储为浮点数.它是两个4字节整数,第一个是自1900-1-1以来的天数,第二个是自午夜以来的1/300秒数.最后,在我看来转换为浮动是不好的做法,因为到达日期时间的往返转换是不可靠的.请参阅[此帖更多详细信息](http://stackoverflow.com/questions/2775/whats-the-best-way-to-remove-the-time-portion-of-a-datetime-value-sql-服务器/ 3696991#3696991).

4> BrianMichael..:

在SQL Server 2012中使用

select cast(getdate() as date)


虽然这是真的,但问题是旧的MS SQL 2000和2005版本缺少`date`数据类型.
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有