Динамическое направление порядка
Я пишу SP, который принимает в качестве столбца параметров сортировку и направление.
Я не хочу использовать динамический SQL.
Проблема заключается в настройке параметра направления.
Это частичный код:
SET @OrderByColumn = 'AddedDate'
SET @OrderDirection=1;
.
.
.
ORDER BY
CASE WHEN @OrderByColumn='AddedDate' THEN CONVERT(varchar(50),AddedDate)
WHEN @OrderByColumn='Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn='AddedBy' THEN AddedBy
WHEN @OrderByColumn='Title' THEN Title
END
Ответы
Ответ 1
У вас могут быть два почти одинаковых элемента ORDER BY, один ASC и один DESC, и продлить ваш оператор CASE, чтобы сделать одно или другое из них всегда равным одному значению:
ORDER BY
CASE WHEN @OrderDirection=0 THEN 1
ELSE
CASE WHEN @OrderByColumn='AddedDate' THEN CONVERT(varchar(50),AddedDate)
WHEN @OrderByColumn='Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn='AddedBy' THEN AddedBy
WHEN @OrderByColumn='Title' THEN Title
END
END ASC,
CASE WHEN @OrderDirection=1 THEN 1
ELSE
CASE WHEN @OrderByColumn='AddedDate' THEN CONVERT(varchar(50),AddedDate)
WHEN @OrderByColumn='Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn='AddedBy' THEN AddedBy
WHEN @OrderByColumn='Title' THEN Title
END
END DESC
Ответ 2
Вы можете упростить CASE, используя ROW_NUMBER, который сортирует ваши данные и эффективно преобразует их в удобный целочисленный формат. Тем более, что вопрос отмечен SQL Server 2005
Это также достаточно легко расширяется, чтобы справляться со вторичными и третичными типами
Я использовал множитель, чтобы снова упростить фактический оператор select и уменьшить вероятность оценки RBAR в ORDER BY
DECLARE @multiplier int;
SELECT @multiplier = CASE @Direction WHEN 1 THEN -1 ELSE 1 END;
SELECT
Columns you actually want
FROM
(
SELECT
Columns you actually want,
ROW_NUMBER() OVER (ORDER BY AddedDate) AS AddedDateSort,
ROW_NUMBER() OVER (ORDER BY Visible) AS VisibleSort,
ROW_NUMBER() OVER (ORDER BY AddedBy) AS AddedBySort,
ROW_NUMBER() OVER (ORDER BY Title) AS TitleSort
FROM
myTable
WHERE
MyFilters...
) foo
ORDER BY
CASE @OrderByColumn
WHEN 'AddedDate' THEN AddedDateSort
WHEN 'Visible' THEN VisibleSort
WHEN 'AddedBy' THEN AddedBySort
WHEN 'Title' THEN TitleSort
END * @multiplier;
Ответ 3
Вот пример:
CREATE PROCEDURE GetProducts
(
@OrderBy VARCHAR(50),
@Input2 VARCHAR(30)
)
AS
BEGIN
SET NOCOUNT ON
SELECT Id, ProductName, Description, Price, Quantity
FROM Products
WHERE ProductName LIKE @Input2
ORDER BY
CASE
WHEN @OrderBy = 'ProductNameAsc' THEN ProductName
END ASC,
CASE
WHEN @OrderBy = 'ProductNameDesc' THEN ProductName
END DESC
END
Отсюда:
http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql
Возрастающие и нисходящие действия быть сгруппированы в отдельный CASE операторов, разделенных запятой. В ваш серверный код / script убедитесь, что добавить "Asc" или "Desc" на порядок по строке, или у вас может быть два Параметры входной записи сохраненной процедуры для имя столбца и порядок по указанию, если вы хотите.
Ответ 4
Это отлично работает для меня - (где, порядок, направление, смещение)
parameters
@orderColumn int ,
@orderDir varchar(20),
@start int ,
@limit int
select * from items
WHERE (items.status = 1)
order by
CASE WHEN @orderColumn = 0 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 0 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'asc' THEN items.[category] END ASC
OFFSET @start ROWS FETCH NEXT @limit ROWS ONLY