2010-10-07 3 views
12

Написание хранимой процедуры в MS SQL Server 2008 R2, я хочу, чтобы избежать использования DSQL ...Условный SQL ORDER BY ASC/DESC для альфа-столбцов

Я хотел бы метод сортировки (ASC или DESC) быть условна.

Теперь, с числовым столбцом я бы просто использовать случай заявление и свести на нет значения для эмуляции ASC или DESC ... То есть:

... ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [NumericColumn] ELSE -[NumericColumn] END ASC 

Что является подходящим методом для этого с альфа-колонка?

EDIT: Я думал об умном способе, но кажется ужасно неэффективным ... Я мог бы вставить свой упорядоченный альфа-столбец в таблицу temp с помощью автонабора, а затем отсортировать по автономеру, используя метод, описанный выше.

EDIT2:

Что вы, ребята, думаете о таком подходе?

ORDER BY CASE @OrderAscOrDesc WHEN 0 THEN [AlphaColumn] ELSE '' END ASC, 
CASE @OrderAscOrDesc WHEN 0 THEN '' ELSE [AlphaColumn] END DESC 

Я не знаю, заставляя своего рода на единой колонны является более эффективным, чем выводе чисел из отсортированных строк, хотя

ответ

27

Один из вариантов

;WITH cQuery AS 
(
    SELECT 
     *, 
     ROW_NUMBER() OVER (ORDER BY SortColumn) AS RowNum 
    FROM 
     MyTable 
) 
SELECT 
    * 
FROM 
    cQuery 
ORDER BY 
    RowNum * @Direction --1 = ASC or -1 = DESC 

Или случай, который ИМХО немного uglier

ORDER BY 
    CASE WHEN 'ASC' THEN SortColumn ELSE '' END ASC, 
    CASE WHEN 'DESC' THEN SortColumn ELSE '' END DESC 
+0

умный, очень похоже на мое решение, которое я разместил в редактировании. Я надеюсь на что-то более эффективное, чем на получение другой сортированной копии данных, чтобы создать числовой порядок сортировки .... – Matthew

+0

@Matthew PK: вам либо нужно подставить строку для соответствующего номера, либо добавить фиктивные сортировки для не- .реальные случаи. Ничего * на самом деле * умный, я боюсь – gbn

+0

Что вы думаете о «двух предложениях ORDER BY» в моем втором редактировании? – Matthew

1

Это один из тех случаев, когда конкретные решения могут быть предпочтительнее prefe но и к общим, особенно когда мы имеем дело с большими объемами данных. Я хотел бы:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM ... 
    ORDER BY [AlphaColumn] DESC 
END 

Если у вас есть индекс на [AlphaColumn], иногда вы можете получить лучший план с более конкретным запросом, чем с родовыми один-размер-подходит-всем один.

Edit: для облегчения повторного использования кода, вы можете обернуть ваш выбор в инлайн UDF - он будет выполнять точно так же:

IF @OrderAscOrDesc = 0 THEN BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] ASC 
END ELSE BEGIN 
    SELECT ... 
    FROM YourInlineUdf(...) 
    ORDER BY [AlphaColumn] DESC 
END 
+0

Я согласен с принципом, изложил. В моем конкретном приложении я бы предпочел не делать этого, потому что запрос относительно длинный и использует несколько соединений. Моя проблема заключалась в том, что код дублируется 6 раз или около того, что затрудняет техническое обслуживание и будущие обновления. – Matthew

+0

@Matthew PK: чтобы облегчить повторное использование кода, вы можете обернуть свой выбор в встроенный UDF - он будет работать так же хорошо –

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