Заказ по и различные типы в случае - PullRequest
6 голосов
/ 07 марта 2011

У меня есть требование упорядочить набор результатов по столбцу на основе целочисленного ввода в параметр.

Проблема в том, что мне нужно использовать CASE для OrderBy, и кажется, что код принимаетпервый 'TYPE' в столбце case ... любые другие типы терпят неудачу.

Мой код такой:

    WITH error_table AS  
 (  
  SELECT Row_Number() OVER   
   (ORDER BY  
        CASE @orderBy
            WHEN 1 THEN received_date  -- Last Rx'd message  
            WHEN 2 THEN message_id -- Message Id  
            WHEN 3 THEN zibmat.short_name -- Message action type  
            WHEN 4 THEN error_action.short_name -- Status type  
            WHEN 5 THEN ime.[allocated_date] -- Allocated Date  
            ELSE received_date
    END) AS RowNumber   

   ,ime.[ijis_message_error_id]  
      ,ime.[message_id]  
      ,ime.[message_version] 

Итак, когда OrderBy равен 1, он работает.Он сортируется по rx_date ... но когда я отправил ему 2, он завершается с ошибкой преобразования времени данных.

Похоже, что все типы должны быть одинаковыми ...

Отправка5 отлично работает, так как это время даты.

Есть ли способ, как я могу это исправить?

Ответы [ 3 ]

10 голосов
/ 07 марта 2011

Оператор CASE должен разрешать только один тип данных. Это независимо от того, что вы знаете, что @orderby выберет только одну ветку, и это будет определенный тип данных.

Вы могли бы использовать что-то вроде этого, что было бы неуклюже, но сработало.

ORDER BY
CASE @orderBy WHEN 1 THEN received_date -- Last Rx'd message
WHEN 2 THEN 0
WHEN 3 THEN 0
WHEN 4 THEN 0
WHEN 5 THEN ime.[allocated_date] -- Allocated Date
ELSE received_date END,
CASE @orderBy WHEN 1 THEN 0
WHEN 2 THEN message_id -- Message Id
WHEN 3 THEN 0
WHEN 4 THEN 0
WHEN 5 THEN 0
ELSE 0 END,
CASE @orderBy WHEN 1 THEN ''
WHEN 2 THEN ''
WHEN 3 THEN zibmat.short_name -- Message action type
WHEN 4 THEN error_action.short_name -- Status type
WHEN 5 THEN ''
ELSE '' END
6 голосов
/ 07 марта 2011

Это также, кажется, работает.

ORDER BY  
        CASE @orderBy
            WHEN 1 THEN CAST(received_date AS SQL_VARIANT)  -- Last Rx'd message  
            WHEN 2 THEN message_id -- Message Id  
            WHEN 3 THEN zibmat.short_name -- Message action type  
            WHEN 4 THEN error_action.short_name -- Status type  
            WHEN 5 THEN ime.[allocated_date] -- Allocated Date  
            ELSE received_date
    END

Контрольный пример (int, string, date)

DECLARE @P INT = Datepart(SECOND, Getdate())%3;

SELECT 'Sorting By ' + CASE @P
            WHEN 1 THEN 'modify_date'
            WHEN 2 THEN 'object_id'
            ELSE 'name'
          END  

SELECT object_id,
       name,
       modify_date
FROM   sys.objects
ORDER  BY CASE @P
            WHEN 1 THEN CAST(modify_date AS SQL_VARIANT)
            WHEN 2 THEN object_id
            ELSE name
          END  
1 голос
/ 23 января 2013

Я думаю, что следующий вариант будет более чистым (аналогично подходу RichardTheKiwi)

WITH error_table AS  
(  
    SELECT ROW_NUMBER() OVER 
            (
            ORDER BY
                CASE WHEN @orderBy = 1 THEN received_date END,
                CASE WHEN @orderBy = 2 THEN message_id END ,
                CASE WHEN @orderBy = 3 THEN zibmat.short_name END,
                CASE WHEN @orderBy =4 THEN error_action.short_name END, 
                CASE WHEN @orderBy =5 THEN ime.[allocated_date] END 
            ) AS RowNumber

    ,ime.[ijis_message_error_id]  
    ,ime.[message_id] 
    --..other columns...
    -- FROM YOURTABLE
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...