我有来自SQL语句的以下片段
ROW_NUMBER() OVER (ORDER BY CASE
WHEN @SortBy = 'column1 ASC' THEN cast(column1 AS sql_variant)
WHEN @SortBy = 'column2 ASC' THEN cast(column2 AS sql_variant)
WHEN @SortBy = 'column3 ASC' THEN cast(column3 AS sql_variant)
WHEN @SortBy = 'column4 ASC' THEN cast(column4 AS sql_variant)
ELSE NULL
END ASC,
CASE
WHEN @SortBy = 'column1 DESC' THEN cast(column1 AS sql_variant)
WHEN @SortBy = 'column2 DESC' THEN cast(column2 AS sql_variant)
WHEN @SortBy = 'column3 DESC' THEN cast(column3 AS sql_variant)
WHEN @SortBy = 'column4 DESC' THEN cast(column4 AS sql_variant)
ELSE NULL
END DESC) AS RowNumber
它有效,但它非常重复,是否有办法使ASC / DESC动态化,所以我不需要重复的CASE
语句?
答案 0 :(得分:1)
您可以这样做的一种方法是在不同的级别定义列别名,这样您就可以引用它两次而不重复表达式。
SELECT *,
Row_number() OVER (ORDER BY
CASE WHEN @SortBy LIKE '% ASC' THEN sort_col END ASC,
CASE WHEN @SortBy LIKE '% DESC' THEN sort_col END DESC) AS RowNumber
FROM YourTable
CROSS APPLY (SELECT CASE
WHEN @SortBy LIKE 'column1 %' THEN Cast(column1 AS SQL_VARIANT)
WHEN @SortBy LIKE 'column2 %' THEN Cast(column2 AS SQL_VARIANT)
WHEN @SortBy LIKE 'column3 %' THEN Cast(column3 AS SQL_VARIANT)
WHEN @SortBy LIKE 'column4 %' THEN Cast(column4 AS SQL_VARIANT)
END) C(sort_col)
我会考虑使用动态SQL。这种捕获所有查询都会破坏获得一个可以使用索引来避免排序的好计划的想法。
答案 1 :(得分:0)
我不确定你是否会认为这更简单。它使用算术操作来获得结果,基于下行行数是总计数减去升序的事实:
((case when @SortBy like '%DESC' then 1 else -1 end) *
(case when @SortBy like '%DESC'
then count(*) over ()
else 0
end) -
(ROW_NUMBER() OVER
(ORDER BY CASE WHEN @SortBy like 'column1%' THEN cast(column1 AS sql_variant)
WHEN @SortBy like 'column2%' THEN cast(column2 AS sql_variant)
WHEN @SortBy like 'column3%' THEN cast(column3 AS sql_variant)
WHEN @SortBy like 'column4%' THEN cast(column4 AS sql_variant)
ELSE NULL
END)
)
)
它确实将列列表限制为一个case语句。