在MS SQL 2000和2005中,给定日期时间,例如'2008-09-25 12:34:56',获得仅包含'2008-09-25'的日期时间的最有效方法是什么?
这里重复一遍.
我必须承认我之前没见过马特所展示的地板浮动转换.我不得不测试一下.
我测试了一个纯粹的选择(它将返回日期和时间,而不是我们想要的),这里的统治解决方案(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方法略快.
在你去那里之前,我多次运行这个测试,查询的顺序发生了变化,同样的结果.
我的服务器上有什么奇怪的东西,或者是什么?
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日)来规避此错误.
select cast(floor(cast(@datetime as float)) as datetime)
之所以有效,因为将日期时间转换为浮点数会给出自1900年1月1日以来的天数(包括一天的分数).地板会删除小数天并留下整天的天数,然后可以将其转换回日期时间.
在SQL Server 2012中使用
select cast(getdate() as date)