SQL Server窗口函数子句中的条件排序顺序

Jez*_*Jez 6 sql t-sql sql-server

所以,这不是你的平均'有条件排序'问题......我在这里有一个相当棘手的问题.:-)我想允许我的存储过程为结果提供条件排序顺序.通常,这可以通过以下方式完成:

SELECT *
INTO #ResultsBeforeSubset
FROM
    MyTable
ORDER BY
    CASE WHEN @SortAscending=1 THEN 'SortColumn' END ASC,
    CASE WHEN @SortAscending=0 THEN 'SortColumn' END DESC
Run Code Online (Sandbox Code Playgroud)

我想CASE围绕实际ASC/ 做一个声明DESC,但这不起作用.上述方法工作的原因是,当@SortAscending不等于给定值时,SQL服务器将CASE语句转换为常量NULL.所以,如果@SortAscending是0,你实际上有:

ORDER BY
    NULL ASC,
    SortColumn DESC
Run Code Online (Sandbox Code Playgroud)

然后,第一个排序表达式什么都不做.这是有效的,因为在常规SELECT语句中,您可以在ORDER BY子句中使用常量.

麻烦的是,我在存储过程中排序的时间是在SELECT包含窗口函数的语句中ROW_NUMBER().因此,我想将CASE语句放在其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
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会在您运行存储过程时导致以下错误:

Windowed functions do not support constants as ORDER BY clause expressions.
Run Code Online (Sandbox Code Playgroud)

因为这是窗口函数的子句,所以将CASE语句转换为常量NULL是无效的.

任何人都可以想到一种方法,我可以有条件地改变UNIONed SELECT的排序顺序,并为这些排序结果的每一行分配行号?我知道我可以将整个查询构造为字符串并将其作为完全动态的SQL执行,但如果可能的话,我宁愿避免使用它.


更新:看起来问题不是由CASE语句本身引起的,而是由于我在CASE语句的条件子句中仅使用常量值.我已经开始了这条奇怪的行为,一个新的问题在这里.

And*_*mar 1

您可以在两个方向上分配行号,并在外部选择一个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
Run Code Online (Sandbox Code Playgroud)

SE Data的工作示例。