2016-03-08 2 views
0

У меня есть оконный запрос, как показано ниже:Сортировка производного столбца в оконном запросе

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) 
      ... 

и я не могу получить его на заказ в производных столбцов (как показано выше). Я был в состоянии сделать заказ производных столбцами с помощью «обычных» запросов с помощью индекса столбца в порядке п IE:

ORDER BY 2 

, но я получаю сообщение об ошибке при попытке выполнить свой оконный запрос, который говорит:

Windowed functions do not support integer indices as ORDER BY clause expressions.

Как я могу заказать производные столбцы, как указано выше?

ТИА

EDIT: Проводка мой фактический код для каждого запроса.

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) 
+0

Все выражения в одной 'п SELECT' вычисляются «как будто» все они оцениваются параллельно - это означает, что между ними не может быть никаких зависимостей, поскольку значения не доступны при запуске оценки. Вам нужно использовать CTE или подзапрос, чтобы ввести другое предложение SELECT, которое (логически) оценивается ранее, а затем помещать выражения «зависящие от» в это предложение. Для сложных цепочек зависимостей вам может потребоваться ввести больше CTE/подзапросов, чтобы сделать эту работу. –

ответ

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) 
+0

Я пробовал маршрут подзапроса, и я получаю эту ошибку: «Недопустимое имя столбца« MyDerivedCol ».» –

+0

Не могли бы вы разместить или добавить комментарий ко всему вашему коду для запроса? – EduardoCMB

+0

добавил «настоящий» код моему OP. Реальная ошибка, которую я получаю, такова: «Недопустимое имя столбца« StudentDissationStageD ».» –