将datetime2的time部分转换为decimal / float

时间:2014-10-14 11:58:03

标签: sql-server function datetime

我正在寻找一种方法来构建搜索datetime2字段中所有正午日期的标准(包括那些具有NULL值的日期)。换句话说,时间部分必须等于0.5或NULL。 以下是我试图找到时间编号:

SELECT cast(GetDate() - DateDiff(day, 0, GetDate()) as decimal(4,4));

它给了我想要的东西,但当我将其作为标准传递时,以下代码失败并出现错误

"操作数类型冲突:datetime2与int"不兼容:

SELECT tbl_OrderDetailsSub.OrderDetailsSubID, ProcessedDate 
FROM tbl_OrderDetailsSub INNER JOIN tbl_OrderDetailsSubPl 
ON tbl_OrderDetailsSub.OrderDetailsSubID = tbl_OrderDetailsSubPl.OrderDetailsSubID 
INNER JOIN tbl_OrderDetails ON tbl_OrderDetailsSub.OrderDetailsID = tbl_OrderDetails.OrderDetailsID 
INNER JOIN tbl_Order ON tbl_OrderDetails.OrderID = tbl_Order.OrderID 
INNER JOIN tbl_Tooling ON tbl_OrderDetailsSubPl.TID = tbl_Tooling.TID LEFT OUTER JOIN tbl_ProdAct ON tbl_OrderDetailsSub.OrderDetailsSubID = tbl_ProdAct.ODSubID
WHERE (((tbl_Order.ProdTypeID)<>'S' Or (tbl_Order.ProdTypeID) Is Null) 
AND ((tbl_Order.CancelledDate) Is Null) 
AND ((tbl_Order.RefusingReason) Is Null)

AND (cast(isnull(ProcessedDate - DateDiff(day, 0, ProcessedDate),0.5) as decimal(4,4))=0.5)

AND ((tbl_Order.OrderType)<>'Pasiūlymas') 
AND ((tbl_Order.ShippedDate) Is Null));

我觉得它与 IsNull 功能有某种关联,但无法澄清它。我也尝试过这一行

AND (cast(ProcessedDate - DateDiff(day, 0, ProcessedDate) as decimal(4,4))=0.5 OR ProcessedDate is null)

...但是得到了同样的错误。

2 个答案:

答案 0 :(得分:0)

试试这个

SELECT tbl_OrderDetailsSub.OrderDetailsSubID,
       ProcessedDate
FROM   tbl_OrderDetailsSub
       INNER JOIN tbl_OrderDetailsSubPl
               ON tbl_OrderDetailsSub.OrderDetailsSubID = tbl_OrderDetailsSubPl.OrderDetailsSubID
       INNER JOIN tbl_OrderDetails
               ON tbl_OrderDetailsSub.OrderDetailsID = tbl_OrderDetails.OrderDetailsID
       INNER JOIN tbl_Order
               ON tbl_OrderDetails.OrderID = tbl_Order.OrderID
       INNER JOIN tbl_Tooling
               ON tbl_OrderDetailsSubPl.TID = tbl_Tooling.TID
       LEFT OUTER JOIN tbl_ProdAct
                    ON tbl_OrderDetailsSub.OrderDetailsSubID = tbl_ProdAct.ODSubID
WHERE  ( ( ( tbl_Order.ProdTypeID ) <> 'S'
            OR ( tbl_Order.ProdTypeID ) IS NULL )
         AND ( ( tbl_Order.CancelledDate ) IS NULL )
         AND ( ( tbl_Order.RefusingReason ) IS NULL )
         AND ( Cast(Isnull(Cast(ProcessedDate AS DATETIME) - Datediff(day, 0, Cast(ProcessedDate AS DATETIME)), 0.5) AS DECIMAL(4, 4)) = 0.5 )
         AND ( ( tbl_Order.OrderType ) <> 'Pasiūlymas' )
         AND ( ( tbl_Order.ShippedDate ) IS NULL ) ); 

答案 1 :(得分:0)

错误是因为您尝试从INT中减去DATETIME2,而INT不能implicitly convertedDATETIME2。这部分有效:

SELECT cast(GetDate() - DateDiff(day, 0, GetDate()) as decimal(4,4));

由于GETDATE()DATETIME,而不是DATETIME2INT可以隐式转换为DATETIME。如果您检查执行计划XML,您将看到

  

CONVERT(十进制(4,4),getdate() - CONVERT_IMPLICIT(datetime,datediff(日,&#39; 1900-01-01 00:00:00.000&#39;,getdate()),0) ,0)

您可以看到INT的{​​{1}}结果被隐式转换为日期时间。

您可以使用以下方法复制同一错误:

datediff(day,'1900-01-01 00:00:00.000',getdate())

我不是100%确定为什么在SQL Server 2008中为DECLARE @D DATETIME2 = GETDATE(); SELECT cast(@D - DateDiff(day, 0, @D) as decimal(4,4)); DATE的新类型删除了隐式转换,但实际上我们必须处理它。

解决此问题的一种方法是将DATETIME2转换为DATETIME2

DATETIME

但是,我倾向于完全避免隐式转换并使用:

DECLARE @D DATETIME2 = GETDATE();
SELECT cast(CAST(@D AS DATETIME) - DateDiff(day, 0, @D) as decimal(4,4));

前提是将您的日期转换为时间,然后查找当天开始的秒数,然后将其除以当天的总秒数,即可得出小数时间。