SQL-запрос 'Order By' (значение даты / времени выходит за пределы диапазона) - PullRequest
3 голосов
/ 02 декабря 2010

У меня проблема с приведенным ниже запросом:

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 ]

2 голосов
/ 02 декабря 2010

Просто прочитав вопрос снова, я не могу объяснить конкретные симптомы, которые вы получаете, не видя плана выполнения (я ожидал, что 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 голосов
/ 02 декабря 2010

Если вы делаете пошаговое упорядочение, то типы данных должны быть совместимы друг с другом.

попробуйте это для даты:

Convert(int, TripDate , 112) 

Формат 112 даст вам ггггммдд, что полезно при упорядочении по дате в виде целого числа. Используйте 1 - [дата] для спуска.

Предполагается, что LegacyID является целым числом. В противном случае вы можете попробовать привести дату к типу SQL_VARIANT

.
0 голосов
/ 02 декабря 2010

Все параметры в операторе CASE должны иметь одинаковый тип данных. LegacyID - это символ?

У вас будет эта проблема где угодно, а не только в порядке. Если вы выполняете CASE WHEN 'x' THEN (некоторые int), WHEN 'y' THEN (некоторые date) и SQL не может выполнить неявное преобразование всех значений, то вы просто тост.

0 голосов
/ 02 декабря 2010

Разве вам не нужно "END" после вашего THEN TripDate?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...