Условный SQL ORDER BY ASC / DESC для альфа-столбцов - PullRequest
14 голосов
/ 07 октября 2010

При написании хранимой процедуры в MS SQL Server 2008 R2 я хочу избежать использования DSQL ...

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

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

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

Какой метод подходит для этого с альфа-столбцом?

РЕДАКТИРОВАТЬ: Я подумал об умном способе, но он кажется ужасно неэффективным ... Я мог бы вставить свой упорядоченный альфа-столбец во временную таблицу с автономным номером, а затем отсортировать по автономному номеру, используя описанный выше метод.

EDIT2:

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

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

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

Ответы [ 2 ]

30 голосов
/ 07 октября 2010

Один вариант

;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

Или СЛУЧАЙ, который ИМХО немного страшнее

ORDER BY
  CASE WHEN 'ASC' THEN SortColumn ELSE '' END ASC,
  CASE WHEN 'DESC' THEN SortColumn ELSE '' END DESC
1 голос
/ 07 октября 2010

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

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

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

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

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