'排序依据'SQL问题(超出范围日期/时间值)

时间:2010-12-02 12:57:06

标签: sql-server tsql datetime

我遇到以下问题的问题:

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是一个'日期时间字段'。

有什么想法吗?

4 个答案:

答案 0 :(得分: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

您需要检查执行计划以进行性能比较。

答案 1 :(得分:0)

你的那个TripDate之后不需要“结束”吗?

答案 2 :(得分:0)

CASE语句中的所有选项必须是相同的数据类型。 LegacyID是char吗?

你在任何地方都会遇到这个问题,而不只是在订单中。如果你做'x'那么情况(某些int)那么'那么'(某个日期)并且SQL无法对所有值进行隐式转换,那么你就是干杯。

答案 3 :(得分:0)

如果您正在进行套装订购,那么数据类型必须相互兼容。

试试这个日期:

Convert(int, TripDate , 112) 

格式为112将为您提供yyyymmdd,这在按日期作为整数排序时非常有用。使用1 - [日期]进行降序。

这假设LegacyID是一个整数。否则,您可以尝试将日期转换为类型SQL_VARIANT