2010-12-02 113 views
3

我在與下面的查詢問題:「ORDER BY」 SQL問題(超出範圍的日期/時間值)

SELECT 
    Consignments.LegacyID, 
    Consignments.TripDate, 
    Consignments.CollectionName, 
    CASE 
     WHEN Sage2.InvoiceSummaryType = 'HT' THEN DeliveryTown 
     ELSE DeliveryName + ', ' + DeliveryTown + ', ' + DeliveryPostCode END AS 'DeliveryName', 
    Consignments.Pallets, 
    Consignments.Weight, 
    Consignments.BaseRate, 
    Consignments.FuelSurcharge, 
    Consignments.AdditionalCharges, 
    Consignments.BaseRate * Consignments.Quantity AS 'InvoiceValue', 
    Consignments.InvoiceNumber, 
    Consignments.Customer 
FROM 
    Consignments 

    INNER JOIN SageAccount 
     ON Consignments.Customer = SageAccount.LegacyID 
     AND SageAccount.Customer = 'true' 

    LEFT OUTER JOIN SageAccount AS Sage2 
     ON SageAccount.InvoiceAccount = Sage2.LegacyID 
WHERE 
    (Sage2.Customer = 'true') 
    AND (Consignments.Customer = @Customer) 
    AND (Consignments.InvoiceNumber IS NOT NULL) 
    OR (Sage2.Customer = 'true') 
    AND (Consignments.InvoiceNumber IS NOT NULL) 
    AND (Sage2.InvoiceAccount = @Customer) 

ORDER BY 
    CASE 
     WHEN Sage2.InvoiceSummaryType = 'HR' THEN TripDate 
     WHEN Sage2.InvoiceSummaryType = 'HS' THEN Consignments.LegacyID 
    END 

出於某種原因,它不斷給我下面的錯誤:

The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value order by

但只有當它試圖Order By TripDate,即當案「HR」發生。 TripDate是一個'日期時間字段'。

任何想法?

回答

2

剛剛讀過這個問題,我無法解釋你沒有看到執行計劃(我會預期HS導致的問題)你得到的具體症狀。但是總的來說,你應該避免在如下CASE表達式混合數據類型,因爲它根本不起作用select case when 1=0 then GETDATE() else 'foo' end會失敗,因爲它試圖將字符串轉換爲datetime

ORDER BY 
     CASE 
        WHEN Sage2.InvoiceSummaryType = 'HR' 
        THEN TripDate 
        WHEN Sage2.InvoiceSummaryType = 'HS' 
        THEN Consignments.LegacyID 
     END 

要解決這個問題,你可以使用cast(TripDate as float) - 假設(也許錯誤地)ID字段是數字或使用這個習慣用法。

ORDER BY 
     CASE 
        WHEN Sage2.InvoiceSummaryType = 'HR' 
        THEN TripDate 
        ELSE NULL 
     END, 
     CASE 
        WHEN Sage2.InvoiceSummaryType = 'HS' 
        THEN Consignments.LegacyID 
        ELSE NULL 
     END 

您需要檢查性能比較的執行計劃。

+0

從某種角度來看,我猜你的懷疑是正確的。在集合包含兩種數據之前可能沒有問題。在那之後,你可能會說他們兩個都會導致問題,或者說他們都不會導致問題,只是一起使用它們而導致錯誤。事實上,正如你所說的那樣,避免混合使用數據類型,或者在將它們用於比較之前將它們強制爲一些常見類型。 +1 – 2010-12-02 13:24:19

+0

感謝哥們,我試過了你的第二個問題,它的工作很完美。 – Chris 2010-12-02 15:04:20

0

在THEN TripDate之後你不需要「結束」嗎?

0

CASE語句中的所有選項都必須是相同的數據類型。 LegacyID是char?

您在任何地方都會遇到此問題,而不僅僅是按順序。如果你在'x'THEN(some int)時做了CASE,那麼當'y'THEN(某個日期)並且SQL不能對所有值進行隱式轉換時,那麼你就是敬酒了。

0

如果您正在做一個套料訂購,那麼數據類型必須相互兼容。

嘗試一下本作日期:

Convert(int, TripDate , 112) 

112的一種格式會給你爲yyyymmdd,這是按日期爲整數排序是有用的。使用1 - [日期]降序。

這是假設LegacyID是一個整數。否則,您可以嘗試將日期轉換爲類型SQL_VARIANT