Подтвердить что ты не робот

Динамическое направление порядка

Я пишу 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
4b9b3361

Ответ 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