我在DataBase中有一个表。表由两列组成。 DeliveryDate的第一列有一种DATETIME类型 DeliveryTime的第二列,其类型为VARCHAR
以下是表格数据的一个小例子
DeliveryDate - DeliveryTime
2014-11-06 00:00:00.000 - 15:00
2014-11-06 00:00:00.000 - 15:00
2014-11-12 00:00:00.000 - 09:00
2014-11-12 00:00:00.000 - 09:00
表中有92行。
目标是创建一个查询,将DeliveryDate和DeliveryTime连接到单个DATETIME列
我提出这样的要求
SELECT CAST((O.DeliveryDate + RIGHT(ISNULL(O.DeliveryTime,'00:00'),5)) AS DATETIME)
FROM MySuperTable
查询失败,并显示varchar无效转换错误
但如果我用TOP进行查询,例如TOP 92.
SELECT TOP 92 CAST((O.DeliveryDate + RIGHT(ISNULL(O.DeliveryTime,'00:00'),5)) AS DATETIME)
FROM MySuperTable
查询完成且没有错误。 此外TOP到620是好的坚果TOP 621再次失败。 请帮助解决顶级逻辑如何工作以及我的代码中的问题
答案 0 :(得分:1)
这是由于查询优化器以及它如何优化查询。它很可能假设它可以重新安排一两步以使事情更快,而不是意识到存在数据问题。这就是为什么
TOP 620
因为它可能影响优化器构建如何获取数据的路径的方式但UDF非常慢。相反,请尝试在查询中更明确,不要将其留给SQL Server,以隐式地将字符串(RIGHT
函数中出来的时间部分)转换为DATETIME
:
SELECT O.DeliveryDate + CONVERT(DATETIME, RIGHT(ISNULL(O.DeliveryTime, '00:00'), 5))
FROM MySuperTable;
答案 1 :(得分:0)
您可以简化查询,请尝试以下查询:
SELECT deliverydate
+ Cast(COALESCE(DeliveryTime, '00:00') AS TIME) AS DeliverDateTime
FROM MySuperTable
但是,我们应该为列使用适当的数据类型。我们有TIME
数据类型来存储时间。
答案 2 :(得分:0)
你有一个空行,它可能是表格中的最后一行。 查找填充NULL的行。
编辑:在“时间”栏中也要仔细查看,可能是某些不正确的时间或不同的格式。
答案 3 :(得分:0)
您的时间价值不合适。以下内容可帮助您找到值:
select t.*
from MySuperTable t
where DeliveryTime not like '[0-5][0-9]:[0-5][0-9]';
您可以将方法与case
:
select (case when DeliveryTime like '[0-5][0-9]:[0-5][0-9]'
then CAST((O.DeliveryDate + RIGHT(ISNULL(O.DeliveryTime,'00:00'),5)) AS DATETIME)
end)
如果您使用的是SQL Server 2012+,也可以使用try_convert()
。
编辑:
另一种可能性是DeliveryDate
有一个时间组件。这又回来了什么?
select DeliveryDate
from MySuperTable
where DeliveryDate <> cast(DeliveryDate as date);
答案 4 :(得分:0)
很奇怪,但是当我在标量函数中将CAST
分开时,一切都开始正常。但很慢:(
CREATE FUNCTION [dbo].[ConcatDateAndTime]
(
@DatePart DATETIME,
@TimePart VARCHAR(50)
)
RETURNS DATETIME
AS
BEGIN
RETURN @DatePart + RIGHT(COALESCE(@TimePart,'00:00'),5)
END