在SQL Server的子查询、视图、内联函数等数据库对象中,不应该单独使用ORDER BY语句

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

SELECT *
FROM
(
    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 *
FROM
(
    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 *
FROM
(
    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语句。

原文地址:https://www.cnblogs.com/OpenCoder/p/12330646.html

时间: 2024-09-29 15:39:59

在SQL Server的子查询、视图、内联函数等数据库对象中,不应该单独使用ORDER BY语句的相关文章

(inline)内联函数在IOS开发中的使用

今天在阅读YYKit源码(https://github.com/ibireme/YYKit.git)时发现在YYKitMacro.h组件中大量使用的内联函数,例如此文件中的一个函数 static inline void dispatch_async_on_main_queue(void (^block)()) { if (pthread_main_np()) { block(); } else { dispatch_async(dispatch_get_main_queue(), block);

测试那些事儿—SQL server exists子查询

exists子查询 --一次性购买“手机数码”产品的数量超过三个的消费金额打8折 --根据已知项查询未知项 --[1]根据类别名称查询类别编号 select sortid from commoditysort where sortname='手机数码‘ --[2]根据类别编号查询商品编号 select commodityid from commodityinfo where sortid= (select sortid from commoditysort where sortname='手机数

SQL Server DBA-日常查询视图

1.查询表名或列名中文注释(sqlserver 2008) select t.object_id,t.name, p.value from sys.tables t join sys.extended_properties p on t.object_id = p.major_id and p.name = 'MS_Description' and p.minor_id=0 ; 1.1查询表名中文注释 select t1.*,t2.name as column_name from (select

C++ 内联函数

1.定义: 被调用函数的函数体代码直接插入到该函数被调用处, 而不是通过call语句进行. 2.方式: (1).类的定义体外: 当在类的定义体外时,需要在该成员函数的定义前面加“inline”关键字,显式地告诉编译器该函数在调用时需要“内联”处理,如: class Person { public: string GetName(); private:   string  name; }; inline string GetName() {         return name; } (2).类

7.4——函数声明,局部对象,内联函数

函数声明: (1)函数在调用之前必须先声明,一个函数可以被声明多次,而只能被调用一次. (2)函数返回值,函数名,函数形参这三个组成函数原型,函数原型描述了函数接口. (3)在头文件中提供函数声明,而在定义函数的的源文件需要包含这个头文件. 局部对象: (1)函数定义的形参和变量的名字只位于函数的作用域中,这些名字只在函数体中可见. (2)自动对象包括函数形参和局部变量,生命周期只存在于函数的执行期间. 静态局部对象(static) (1)若是一个对象位于函数的作用域内,但生命周期存在于函数的多

面向对象程序设计-C++_课时18内联函数

使用inline说明的函数称内联函数. 在C++中,除具有循环语句.switch语句的函数不能说明为内联函数外,其他函数都可以说明为内联函数. 1 #include <iostream> 2 using namespace std; 3 4 inline int f(int i) 5 { 6 return i * 2; 7 } 8 9 void main() 10 { 11 int a(4); 12 int b = f(a); 13 14 std::cout << a <&l

【转】inline内联函数

技术类笔试题50%都会问宏与inline的区别,自己去找找看? 1)宏替换发生在预编译 2)宏函数(如果可以这么叫的话)替换时不会检查参数,inline函数会检查 3)宏一定会发生替换,inline貌似不是强制的,编译器想不替换也没关系 4)宏替换时存在着一些不可避免的陷阱(参见C Traps and Pitfalls),例如传参时如果传了a++之类的可能会出错,inline就比较安全了. 宏有副作用,比如MAX(x++,y++) inline会不同, 慎用内联内联能提高函数的执行效率,为什么不

深入探讨 内联函数和宏定义的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题: 1)内联函数的定义性声明应该出现在

C/C++之宏、内联函数和普通函数的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题:     1)内联函数的定义性声明应