在窗口查询中按派生列排序

时间:2016-03-08 23:20:42

标签: sql-server sql-order-by

我有一个窗口查询,如下所示:

SELECT *
FROM
    (
        SELECT COUNT(*) OVER (PARTITION BY NULL) AS TotalRows,
        ROW_NUMBER() OVER
        (
            ORDER BY MyDerivedColumn asc
        ) AS RowNumber
        ,MyDerivedColumn = (SELECT TOP 1 SomeColumn FROM SomeTable ORDER BY SomeOtherColumn DESC)
            ...

我无法通过派生列进行排序(如上所示)。我已经能够使用“常规”查询通过使用order by子句IE中的列索引来使用派生列进行排序:

ORDER BY 2

但是在尝试执行我的窗口查询时出现错误:

  

窗口函数不支持整数索引作为ORDER BY子句表达式。

如何通过上面的派生列订购?

TIA

编辑:根据请求发布我的实际代码。

    SET @SQL = '
SELECT *
FROM
    (
        SELECT COUNT(*) OVER (PARTITION BY NULL) AS TotalRows,
        ROW_NUMBER() OVER
        (
            ORDER BY StudentDissertationStageDescription ASC
        ) AS RowNumber,
        sc.FirstName
        ,sc.LastName
        ,sc.StudentId
        ,spos.ProgramOfStudy AS ProgramOfStudy
        ,(
            SELECT TOP 1 [StudentDissertationStageDescription]
            FROM
                [StudentDissertationStage] AS sd
            WHERE sc.StudentId = sd.StudentId
            ORDER BY sd.[StudentDissertationStage] DESC
        ) AS StudentDissertationStageDescription 
    FROM 
        StudentClasses AS sc
    LEFT JOIN
        StudentProgramOfStudy AS spos
    ON
        spos.StudentId = sc.StudentId
    LEFT JOIN [dbo].[FacultyAssignments] fa 
         ON sc.StudentId = fa.StudentID
    WHERE 1 = 1
    '
    IF @filter IS NOT NULL
    BEGIN
        SET @SQL = @SQL + @filter
    END
    SET @SQL = @SQL + '
    GROUP BY
        sc.FirstName
        ,sc.LastName
        ,sc.SyStudentID
        ,spos.ProgramOfStudy
    ) AS TheTableSet
    WHERE
        RowNumber BETWEEN ' + 
        CONVERT(nvarchar(10), @startrow) + 
        ' AND ' + 
        CONVERT(nvarchar(10), @endrow) + ''
    EXEC(@SQL)

1 个答案:

答案 0 :(得分:1)

这是你想要的吗?

;with cte as (
    select
        1 as num,
        (SELECT TOP 1 SomeColumn FROM SomeTable ORDER BY SomeOtherColumn DESC) as MyDerivedColumn
)
SELECT
    COUNT(*) OVER (PARTITION BY NULL) AS TotalRows,
    ROW_NUMBER() OVER (ORDER BY MyDerivedColumn asc) AS RowNumber
FROM cte

您还可以使用子查询编写该查询:

SELECT
    COUNT(*) OVER (PARTITION BY NULL) AS TotalRows,
    ROW_NUMBER() OVER (ORDER BY MyDerivedColumn asc) AS RowNumber
FROM (
    select
        1 as num,
        (SELECT TOP 1 SomeColumn FROM SomeTable ORDER BY SomeOtherColumn DESC) as MyDerivedColumn
) t

这样,您的代码看起来像这样:

SET @SQL = '
SELECT *
FROM
    (
        SELECT
            COUNT(*) OVER (PARTITION BY NULL) AS TotalRows,
            ROW_NUMBER() OVER (ORDER BY StudentDissertationStageDescription ASC) AS RowNumber,
            sc.FirstName,
            sc.LastName
            sc.StudentId
            spos.ProgramOfStudy AS ProgramOfStudy
        FROM (
            sc.FirstName,
            sc.LastName,
            sc.StudentId,
            spos.ProgramOfStudy AS ProgramOfStudy,
            (
                SELECT TOP 1 [StudentDissertationStageDescription]
                FROM [StudentDissertationStage] AS sd
                WHERE sc.StudentId = sd.StudentId
                ORDER BY sd.[StudentDissertationStage] DESC
            ) AS StudentDissertationStageDescription,
            DissertationChair = staff.[FirstName] + '' '' + staff.[LastName],
            DissertationEmail = staff.[email]
            FROM StudentClasses AS sc
            LEFT JOIN StudentProgramOfStudy AS spos ON spos.StudentId = sc.StudentId
            LEFT JOIN [dbo].[FacultyAssignments] fa ON sc.StudentId = fa.StudentID
            WHERE 1 = 1
            '
            IF @filter IS NOT NULL
            BEGIN
                SET @SQL = @SQL + @filter
            END
            SET @SQL = @SQL + '
        ) t
        GROUP BY
            t.FirstName,
            t.LastName,
            t.SyStudentID,
            t.ProgramOfStudy
    ) AS TheTableSet

    WHERE
        RowNumber BETWEEN ' + CONVERT(nvarchar(10), @startrow) + ' AND ' + CONVERT(nvarchar(10), @endrow)

EXEC(@SQL)