在MS SQL 2000和2005中,给定日期时间,例如“ 2008-09-25 12:34:56”,获取仅包含“ 2008-09-25”的日期时间的最有效方法是什么?
在这里重复。
在MS SQL 2000和2005中,给定日期时间,例如“ 2008-09-25 12:34:56”,获取仅包含“ 2008-09-25”的日期时间的最有效方法是什么?
在这里重复。
Answers:
我必须承认,我以前从未见过Matt展示的下浮率转换。我必须对此进行测试。
我测试了一个纯选择(将返回日期和时间,而这不是我们想要的),这里是统治性解决方案(floor-float),这里提到了一个常见的“天真”方案(stringconvert),而这里提到的是使用(因为我认为这是最快的)。
我在运行Win 2003 SP2 Server的测试服务器MS SQL Server 2005上测试了查询,而Xeon 3GHz CPU运行在最大内存上(32位,因此约为3.5 Gb)。那天晚上我在这里,所以机器几乎没有负载空转。我已经掌握了一切。
这是我的测试运行中的日志,该日志是从一个大型表中选择的,该表包含从毫秒到毫秒的时间戳。这个特定的数据集包含2.5年以上的日期。该表本身有1.3亿行,所以这就是为什么我限制在前100万行。
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毫秒,经过的时间= 1毫秒。
(受影响的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毫秒,经过的时间= 33440毫秒。SQL Server解析和编译时间:CPU时间= 0毫秒,经过的时间= 1毫秒。
SQL Server执行时间:CPU时间= 0毫秒,经过的时间= 1毫秒。
我们在这里看到什么?
让我们关注CPU时间(我们正在研究转换),我们可以看到有以下数字:
Pure-Select: 422
Floor-cast: 625
String-conv: 1953
DateAdd: 531
由此看来,DateAdd(至少在这种情况下)比现场直播方法要快一些。
在您去那里之前,我多次运行了此测试,查询的顺序已更改,结果相同。
这在我的服务器上有点奇怪吗?
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日以来的天数(包括一天的小数部分)。对其进行地板处理将除去小数天并保留整天的数目,然后可以将其转换回日期时间。
要获取YYYY-MM-DD,请使用:
select convert(varchar(10), getdate(), 120)
编辑:糟糕,他希望使用DateTime而不是字符串。与Oracle中的TRUNC()等效。您可以将我发布的内容投射回DateTime:
select convert(datetime, convert(varchar(10), getdate(), 120) , 120)
以下链接中描述了三种方法。我尚未对它们进行性能测试以确定最快的方法。
CAST(FLOOR(CAST(yourdate AS DECIMAL(12, 5))) AS DATETIME)
迄今为止表现最好。在SQL Server中获取没有时间的日期时,您可以看到证明和测试
那SELECT CAST(CASt(GETDATE() AS int) AS DATETIME)
??