我们知道在SQL语句中,ORDER BY语句可以用来排序。但是在SQL Server中,如果我们在子查询、视图、内联函数等数据库对象中单独使用ORDER BY语句是不允许的,来看下面的SQL语句:

SELECT * 
    SELECT [ID],[Code],[Name],[Age],[Sex],[Class]
    FROM [dbo].[Student]
    ORDER BY [ID] DESC
) AS T_Student

执行该语句,SQL Server会报错,错误信息如下:

The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.

该错误信息明确地指出ORDER BY语句不能够在子查询、视图、内联函数等数据库对象中使用, 除非是用了TOP、OFFSET、FOR XML语句

这个错误是微软想让开发者明白一个道理,那就是像子查询、视图、内联函数等这种中间结果查询,是不应该负责对查询结果进行排序的, 对查询结果排序是最外层查询才应该做的事情,而不是中间结果查询该做的事

那么为什么加了TOP、OFFSET、FOR XML语句后,子查询、视图、内联函数等数据库对象中就可以用ORDER BY语句了呢?那是因为这时ORDER BY语句只起到数据筛选的作用,并不是对查询结果排序。举个例子,如果我们要得到[Student]表中[ID]列最大的5条数据记录,就可以在子查询中将ORDER BY语句和TOP语句放在一起使用,如下所示:

SELECT * 
    SELECT TOP 5 [ID],[Code],[Name],[Age],[Sex],[Class]
    FROM [dbo].[Student]
    ORDER BY [ID] DESC
) AS T_Student

这个SQL语句是不会报错的,执行结果如下:

所以我们可以看到[ID]列最大的5条数据记录,就被查询出来了。但是我们前面说了ORDER BY语句在子查询、视图、内联函数等数据库对象中只起到数据筛选的作用,所以如果我们真的想对[ID]列排序,应该在最外层查询再使用ORDER BY语句(虽然上面截图的查询结果中,数据已经按照[ID]列的降序排列,但事实上SQL Server并不保证每次查询结果肯定是按照[ID]列降序排列,你可以认为这只是一个 巧合 ),如下所示:

SELECT * 
    SELECT TOP 5 [ID],[Code],[Name],[Age],[Sex],[Class]
    FROM [dbo].[Student]
    ORDER BY [ID] DESC
) AS T_Student
ORDER BY [ID] DESC

所以真正起到对查询结果进行排序的是最外层查询的ORDER BY语句,而不是子查询中的ORDER BY语句。