2014-10-14 2 views
1

Я ищу способ построить критерии для поиска всех полуденных дат в поле datetime2 (включая значения, имеющие значение NULL). Другими словами, временная часть должна быть равна 0,5 или NULL. Вот что я tryied найти количество времени:Преобразование времени части datetime2 в decimal/float

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

Это дает мне то, что я хочу, но когда я передать его в качестве критериев следующего кода с ошибкой

«типа Операнда столкновения: datetime2 несовместим с межд ":

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) 

... но получил такую ​​же ошибку.

ответ

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)); 
0

Ошибка в том, что вы пытаетесь вычитать INT из DATETIME2 и INT не может быть implicitly converted к DATETIME2. Эта часть работы:

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

Поскольку GETDATE() является DATETIME, не DATETIME2 и INT может быть неявно преобразован в DATETIME. Если вы проверяете план выполнения XML вы увидите

CONVERT (десятичное (4,4), GetDate() - CONVERT_IMPLICIT (DateTime, DATEDIFF (день, '1900-01-01 00: 00: 00.000', GETDATE()), 0), 0)

Где вы можете увидеть, что INT результат datediff(day,'1900-01-01 00:00:00.000',getdate()) в настоящее время неявно преобразован в DateTime.

Вы можете реплицировать ту же ошибку с помощью:

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

Я не 100% уверен, почему неявное преобразование было удалено из-за новых видов DATE и DATETIME2 в SQL Server 2008, но это было, так что мы должны иметь дело с этим.

Один из способов обойти это было бы просто преобразовать ваш DATETIME2 к DATETIME:

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

Однако, я был бы склонен избегать неявных преобразований полностью и использование:

DECLARE @D DATETIME2 = GETDATE(); 
SELECT CAST(DATEDIFF(SECOND, '00:00', CAST(@D AS TIME))/86400.0 AS DECIMAL(10, 4)); 

Предпосылка существо конвертируя дату в определенное время, а затем выясняя количество секунд до начала дня, а затем разделив это на полные секунды в день, вы получите десятичное время.

Смежные вопросы