2010-12-02 114 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