因此,这不是您的平均“条件排序依据”问题……我这里有一个非常棘手的问题。:-)我想允许我的存储过程为结果提供条件排序顺序。通常,可以通过以下方式完成此操作:
SELECT * INTO #ResultsBeforeSubset FROM MyTable ORDER BY CASE WHEN @SortAscending=1 THEN 'SortColumn' END ASC, CASE WHEN @SortAscending=0 THEN 'SortColumn' END DESC
我想CASE围绕实际ASC/声明DESC,但这不起作用。上面的方法起作用的原因是因为,当@SortAscending不等于给定值时,SQL Server会将CASE语句转换为常数NULL。因此,如果@SortAscending为0,则实际上有:
CASE
ASC
DESC
@SortAscending
NULL
ORDER BY NULL ASC, SortColumn DESC
那么,第一个排序表达式什么也不做。之所以可行,是因为SELECT您可以在常规语句中在ORDER BY子句中使用常量。
SELECT
ORDER BY
麻烦的是,我在存储过程中进行排序的时间是在SELECT包含窗口函数的语句期间ROW_NUMBER()。因此,我想将该CASE语句放在其OVER子句中,如下所示:
ROW_NUMBER()
OVER
SELECT * INTO #ResultsBeforeSubset FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY CASE WHEN @SortAscending=1 THEN rowValues.[SortColumn] END ASC, CASE WHEN @SortAscending=0 THEN rowValues.[SortColumn] END DESC ) AS RowNumber, * FROM ( -- UNIONed SELECTs returning rows go here... ) rowValues ) rowValuesWithRowNum
不幸的是,这会在您运行存储过程时导致以下错误:
Windowed functions do not support constants as ORDER BY clause expressions.
因为这是窗口函数的子句,所以将CASE语句转换为常量NULL是无效的。
谁能想到有条件地改变UNIONedSELECT的排序顺序,并为这些排序结果产生的每一行分配行号的方法?我知道我可以求助于将整个查询构造为字符串并将其作为完全动态的SQL执行,但是如果可能的话,我宁愿避免这样做。
UNION
您可以在两个方向分配行号,然后在外部选择一个order by:
order by
select * from ( select row_number() over (order by SortColumn) rn1 , row_number() over (order by SortColumn) rn2 , * from @t ) as SubQueryAlias order by case when @asc=1 then rn1 end , case when @asc=0 then rn2 end desc