2009-04-02 3 views
4

У меня есть следующий SQL в хранимой процедуре. Есть ли способ удалить оператор IF и передать параметр «ASC»/«DESC» в качестве переменной?Могу ли я сохранить порядок сортировки SQL Server в переменной?

Я знаю, что мог бы сделать запрос несколькими различными способами или вернуть таблицу и отсортировать ее извне и т. Д. Я просто хотел бы знать, могу ли я избежать дублирования оператора CASE.

IF @sortOrder = 'Desc' 
    BEGIN 
    SELECT * FROM #t_results 
    ORDER BY 
    CASE WHEN @OrderBy = 'surname'   THEN surname END DESC, 
    CASE WHEN @OrderBy = 'forename'   THEN forename END DESC, 
    CASE WHEN @OrderBy = 'fullName'   THEN fullName END DESC, 
    CASE WHEN @OrderBy = 'userId'   THEN userId END DESC, 
    CASE WHEN @OrderBy = 'MobileNumber'  THEN MSISDN END DESC, 
    CASE WHEN @OrderBy = 'DeviceStatus'  THEN DeviceStatus END DESC, 
    CASE WHEN @OrderBy = 'LastPosition'  THEN LastPosition END DESC, 
    CASE WHEN @OrderBy = 'LastAlert'   THEN LastAlert END DESC, 
    CASE WHEN @OrderBy = 'LastCommunication' THEN LastCommunication END DESC, 
    CASE WHEN @OrderBy = 'LastPreAlert'  THEN LastPreAlert END DESC 
    END 
ELSE 
    BEGIN 
    SELECT * FROM #t_results 
    ORDER BY 
    CASE WHEN @OrderBy = 'surname'   THEN surname END DESC, 
    CASE WHEN @OrderBy = 'forename'   THEN forename END DESC, 
    CASE WHEN @OrderBy = 'fullName'   THEN fullName END DESC, 
    CASE WHEN @OrderBy = 'userId'   THEN userId END DESC, 
    CASE WHEN @OrderBy = 'MobileNumber'  THEN MSISDN END DESC, 
    CASE WHEN @OrderBy = 'DeviceStatus'  THEN DeviceStatus END DESC, 
    CASE WHEN @OrderBy = 'LastPosition'  THEN LastPosition END DESC, 
    CASE WHEN @OrderBy = 'LastAlert'   THEN LastAlert END DESC, 
    CASE WHEN @OrderBy = 'LastCommunication' THEN LastCommunication END DESC, 
    CASE WHEN @OrderBy = 'LastPreAlert'  THEN LastPreAlert END DESC 
    END 
END 

ответ

12

проходит в @OrderBy междунаре, где положительный является ASC, отрицательным является DESC, фактическое число столбца для сортировки по

SELECT 
    dt.yourColumn1 
     ,dt.yourColumn2 
     ,dt.yourColumn3 
     ,CASE 
      WHEN @OrderBy>0 THEN dt.SortBy 
      ELSE NULL 
     END AS SortByAsc 
     ,CASE 
      WHEN @OrderBy<0 THEN dt.SortBy 
      ELSE NULL 
     END AS SortByDesc 
    FROM (SELECT 
       yourColumn1 
        ,yourColumn2 
        ,yourColumn3 
        ,CASE 
         WHEN ABS(@OrderBy) = 1 THEN surname 
         WHEN ABS(@OrderBy) = 2 THEN forename 
         WHEN ABS(@OrderBy) = 3 THEN fullName 
         WHEN ABS(@OrderBy) = 4 THEN CONVERT(varchar(10),userId) 
         WHEN ABS(@OrderBy) = 5 THEN CONVERT(varchar(10),MobileNumber 
         WHEN ABS(@OrderBy) = 6 THEN DeviceStatus 
         WHEN ABS(@OrderBy) = 7 THEN LastPosition 
         WHEN ABS(@OrderBy) = 8 THEN CONVERT(varchar(23),LastAlert,121) 
         WHEN ABS(@OrderBy) = 9 THEN CONVERT(varchar(23),LastCommunication,121) 
         WHEN ABS(@OrderBy) =10 THEN CONVERT(varchar(23),LastPreAlert,121) 
         ELSE NULL 
        END AS SortBy 
       FROM YourTablesHere 
       WHERE X=Y 
     ) dt 
    ORDER BY SortByAsc ASC, SortByDesc DESC 

просто убедитесь, что вы строите строку, вроде правильно, заметьте, что я использовал «YYYY- MM-DD hh: mm: ss.mmm 'для дат и поместить числа в строки. Обычно мы помещаем несколько столбцов, поэтому, если вы сортируете по фамилии, используется имя forename и т. Д. Остерегайтесь, если вы объединяете несколько столбцов, вам нужно заполнить нулями или пробелами.

Если вы не хотите, чтобы столбцы SortByAsc и SortByDesc находились в наборе результатов, оберните всю вещь в производную таблицу.

+0

Им не обязательно быть в производной таблице или в результирующем наборе. Вы можете использовать выражения в предложении ORDER BY. Я только что представил пример, прежде чем увидел ваш ответ. +1: Хорошая точка при синхронизации типов данных. –

+0

, чтобы устранить дублированный оператор CASE, он должен быть столбцом –

6

Да, но вам нужно использовать динамические запросы.

Посмотрите here.

+1

Следует учитывать, что динамические запросы имеют свои проблемы. Это особенно верно, так как вы не полностью контролируете строку (например, SQL Injection). – Richard

7

Вы можете сделать это без динамического SQL ...

SELECT 
    * 
FROM 
    My_Table 
WHERE 
    Whatever = @something 
ORDER BY 
    CASE @sort_order 
      WHEN 'ASC' THEN 
       CASE @order_by 
        WHEN 'surname' THEN surname 
        WHEN 'forename' THEN forename 
        WHEN 'fullname' THEN fullname 
        ELSE surname 
       END 
      ELSE '1' 
    END ASC, 
    CASE @sort_order 
      WHEN 'DESC' THEN 
       CASE @order_by 
        WHEN 'surname' THEN surname 
        WHEN 'forename' THEN forename 
        WHEN 'fullname' THEN fullname 
        ELSE surname 
       END 
      ELSE '1' 
    END DESC 
+0

Я пересмотрел свой код, они спрашивают, как устранить дублирование оператора CASE. Я не думаю, что это можно сделать в ORDER BY. Кроме того, мне нравится мой положительный/отрицательный параметр сортировать лучше, легко в приложении несколько на -1, чтобы переключить его, а значение - номер столбца сетки. –

+0

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

+0

@mike Извините, прокомментировал, прежде чем я увидел ваш комментарий –

1

Как об этом:

CASE WHEN @order_by = @order_by THEN @order_by END 

Тогда нет никаких причин, чтобы иметь несколько случаев.

Смежные вопросы