SQL最快的比较两个日期的方法(非标准varchar格式和日期时间)

时间:2010-09-23 19:03:34

标签: sql sql-server performance sql-server-2008

我需要加入两个“日期”字段。

第一个是yyyy-mm-dd hh:mm:ss

格式的正常日期时间

第二个是红头步骤子格式mmddyyyy

中的varchar(8)

现在这很痛苦,因为没有简单的方法可以转换为相应的类型。有一种内置格式yyyymmdd但与varchar格式不匹配。

我可以看到两条路径:

declare @normal_date as datetime;
declare @hated_date as varchar(8);

set @normal_date='1974-11-01 00:00:00.000'
set @hated_date='11011974'

--cast to date time with string splits
select @normal_date
where CONVERT(datetime, RIGHT(@hated_date,4)+LEFT(@hated_date,2)+SUBSTRING(@hated_date,3,2))=@normal_date

--convert normal date to ackward format
select @normal_date
      where REPLACE(CONVERT(varchar(10),@normal_date,101), '/','')=@hated_date

哪个更好?或者有更好的方法吗?

已编辑以显示费用

--Operator cost (39%)
CONVERT(datetime, RIGHT(@hated_date,4)+LEFT(@hated_date,2)+SUBSTRING(@hated_date,3,2))=@normal_date

--Operator cost (57%)
REPLACE(CONVERT(varchar(10),@normal_date,101), '/','')=@hated_date

--Operator cost (46%)
cast(stuff(stuff(@hated_date, 3,0, '/'),6,0,'/') as datetime)=@normal_date

--Operator cost (47%)
RIGHT(@hated_date, 4) + LEFT(@hated_date, 4)=@normal_date

4 个答案:

答案 0 :(得分:5)

这是yyyymmdd没有?

RIGHT(@hated_date, 4) + LEFT(@hated_date, 4)

所以,你的脚本变成了

declare @normal_date as datetime;
declare @hated_date as varchar(8);

set @normal_date='1974-11-01 00:00:00.000'
set @hated_date='11011974'

--SELECT @hated_date = RIGHT(@hated_date, 4) + LEFT(@hated_date, 4))

select 'hurrah' WHERE @normal_date = RIGHT(@hated_date, 4) + LEFT(@hated_date, 4)

答案 1 :(得分:2)

试试这个:

select cast(stuff(stuff('11011974', 3,0, '/'),6,0,'/') as datetime)

<强>更新

alt text

答案 2 :(得分:2)

另一种方法是:

MONTH(@normal_date)*1000000 + DAY(@normal_date)*10000 + YEAR(@normal_date)
=
CAST(@hated_date AS INT)

还有一件事:比较实际执行成本比依赖优化器估算更准确。

答案 3 :(得分:2)

建议您将列修复为datetime或将datetime列添加到表中并转换数据,这样您只需在输入数据时进行一次转换(当然对于现有数据一次) probaly甚至是一个计算列。这不是你想要在select语句中做的事情。如果需要,在两个格式中创建一个包含每个可能日期的日期转换表,如果无法更改表,则加入该表。

您可能还需要检查以确保其中没有无效日期,将日期存储在日期时间以外的数据类型中始终是可能的。