29

並べ替えと方向のパラメーター列として受け入れる 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
4

6 に答える 6

39

2つのほぼ同一のORDER BYアイテム(1つとASC1つ)を作成しDESC、ステートメントを拡張してCASE、それらのいずれかが常に1つの値に等しくなるようにすることができます。

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
于 2009-07-18T15:27:19.700 に答える
12

データを並べ替えて効果的に便利な整数形式に変換する ROW_NUMBER を使用することで、CASE を単純化できます。特に、質問には SQL Server 2005 というタグが付けられているため

これはまた、二次および三次ソートを処理するのに十分なほど簡単に拡張できます

乗数を使用して、実際の select ステートメントを単純化し、ORDER BY で RBAR が評価される可能性を減らしました。

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;
于 2009-07-18T17:19:58.380 に答える
5

次に例を示します。

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ステートメントにグループ化する必要があります。サーバー側のコード/スクリプトでは、必ず「Asc」または「Desc」を文字列による順序に追加してください。または、必要に応じて、列名と方向による順序に2つのストアドプロシージャ入力パラメーターを設定できます。

于 2009-07-18T15:23:33.920 に答える
5

これは私にとってはうまくいきます – ( where, order by, direction, Pagination)

parameters

@orderColumn  int ,
@orderDir  varchar(20),
@start  int ,
@limit  int


select * from items

order by 

CASE WHEN @orderColumn = 0 AND @orderdir = 'desc' THEN items.[CategoryName] END DESC,    
CASE WHEN @orderColumn = 0 AND @orderdir = 'asc' THEN items.[CategoryName] END ASC,    
CASE WHEN @orderColumn = 1 AND @orderdir = 'desc' THEN items.[CategoryValue] END DESC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'asc' THEN items.[CategoryValue] END ASC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'desc' THEN items.[CreatedOn] END DESC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'asc' THEN items.[CreatedOn] END ASC

OFFSET @start ROWS FETCH NEXT @limit ROWS ONLY
于 2015-12-30T08:37:17.003 に答える