Dynamic order direction Dynamic order direction sql-server sql-server

Dynamic order direction


You could have two near-identical ORDER BY items, one ASC and one DESC, and extend your CASE statement to make one or other of them always equal a single value:

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


You can simplify the CASE by using ROW_NUMBER which sorts your data and effectively converts it into a handy integer format. Especially since the question is tagged SQL Server 2005

This also expands easily enough to deal with secondary and tertiary sorts

I've used multiplier to again simplify the actual select statement and reduce the chance of RBAR evaluation in the ORDER BY

DECLARE @multiplier int;SELECT @multiplier = CASE @Direction WHEN 1 THEN -1 ELSE 1 END;SELECT     Columns you actually wantFROM    (    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...    ) fooORDER BY     CASE @OrderByColumn        WHEN 'AddedDate' THEN AddedDateSort        WHEN 'Visible' THEN VisibleSort            WHEN 'AddedBy' THEN AddedBySort        WHEN 'Title' THEN TitleSort     END * @multiplier;


Here is an example:

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

From here:

http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql

Ascending and Descending actions need to be grouped into separate CASE statements, separated with a comma. In your server-side code/script make sure to append 'Asc' or 'Desc' onto the order by string, or you could have two Stored procedure input parameters for column name and order by direction if you want.