共计 3387 个字符,预计需要花费 9 分钟才能阅读完成。
今天就跟大家聊聊有关 ORDER BY 的用法都有哪些,可能很多人都不太了解,为了让大家更加了解,丸趣 TV 小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
小伙伴们在进行 SQL 排序时,都能很自然的使用到 ORDER BY。不管是默认 ASC 的升序,还是 DESC 降序,几乎都是信手拈来。
今天给大家分享一些你可能不知道的 ORDER BY 用法。
一、ORDER BY 返回的是游标而不是集合
SQL 的理论其实是集合论,常见的类似求数据的交集、并集、差集都可以使用集合的思维来求解。
集合中的行之间没有预先定义的顺序,它只是成员的一种逻辑组合,成员之间的顺序无关紧要。
如下图,每一个括号里的内容就是一条记录,在没排序前,他们都是随机分布在集合中。
Student(ID,Name,Age)
Student 集合
但是对于带有排序作用的 ORDER BY 子句的查询,它返回的是一个对象,其中的行按特定的顺序组织在一起,我们把这种对象称为游标。
如下图,经过对 Student 表的 ID 进行 ORDER BY 排序后,Student 表变成了有序对象,也就是我们上面说的游标。
Student(ID,Name,Age)
Student 对象
二、ORDER BY 子句是唯一能重用列别名的一步
注:markdown 对代码块的语法是开始和结束行都要添加:“`, 其中 ` 为 windows 键盘左上角那
这里涉及 SQL 语句的语法顺序和执行顺序了,我们常见的 SQL 语法顺序如下:
SELECT DISTINCT Top Num select list FROM [left_table] join_type JOIN right_table ON join_condition WHERE where_condition GROUP BY group_by_list WITH CUBE | RollUP HAVING having_condition ORDER BY order_by_list
而数据库引擎在执行 SQL 语句并不是从 SELECT 开始执行,而是从 FROM 开始,具体执行顺序如下(关键字前面的数字代表 SQL 执行的顺序步骤):
(8)SELECT (9)DISTINCT (11) Top Num select list (1)FROM [left_table] (3) join_type JOIN right_table (2) ON join_condition (4)WHERE where_condition (5)GROUP BY group_by_list (6)WITH CUBE | RollUP (7)HAVING having_condition (10)ORDER BY order_by_list
从上面可以看到 SELECT 在 HAVING 后才开始执行,这个时候 SELECT 后面列的别名只对后续的步骤生效,而对 SELECT 前面的步骤是无效的。所以如果你在 WHERE,GROUP BY,或 HAVING 后面使用列的别名均会报错。
我们举例测试一下。
示例表 Customers 结构及数据如下:
1、WHERE 后面不使用别名的情况
SELECT 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers WHERE 城市 = 广州
结果如下:
2、WHERE 后面使用列别名的情况
SELECT 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers WHERE City= 广州
执行结果如下:
从返回的消息中我们可以看到,重命名后的 City 并不能被 WHERE 识别,所以才会报“列名 City 无效”的提示。
其他关键字大家也可以使用上述方法进行测试,下面我们测试 GROUP BY 和 HAVING 后面使用列别名的情况。
3、测试 GROUP BY 后使用列别名
SELECT 城市 AS City FROM Customers GROUP BY City
结果如下:
4、测试 HAVING 后使用列别名
SELECT 城市 AS City FROM Customers GROUP BY 城市 HAVING COUNT(City) 1
结果如下:
5、测试 ORDER BY 后面使用列别名
SELECT 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers ORDER BY City
结果如下:
从上面的几个测试示例的结果中,可以得出我们的结论是正确的:ORDER BY 子句是唯一能重用列别名的一步。
三、谨慎使用 ORDER BY 后面接数字的方式来进行排序
有些小伙伴为了图省事,喜欢在 ORDER BY 后面写数字,具体示例如下:
SELECT 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers ORDER BY 1,2,3
结果如下:
这样写的结果,针对当前的查询是正确没有问题的,ORDER BY 后面的数字 1,2,3 分别代表 SELECT 后面的第 1,第 2,第 3 个字段(也就是 Name,Address,City)。
可是当查询的列发生改变,忘了修改 ORDER BY 列表。特别是当查询语句很长时,要找到 ORDER BY 与 SELECT 列表中的哪个列相对应会非常困难。
例如:
SELECT 客户 ID AS ID, 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers ORDER BY 1,2,3
由于增加了一列“客户 ID”,原本的题意还是对 Name,Address,City 排序,但是因为使用了 ORDER BY 加数字,排序后的结果如下:
得到的结果并不是我们想要的,所以请慎用 ORDER BY 加数字,尽量使用 ORDER BY 加列名或列别名。
四、表达式不能使用 ORDER BY 排序
表表达式包括视图,内联表值函数,派生表 (子查询) 和公用表表达式(CTE)。
例如下面的视图是无效的
CREATE VIEW V_Customers AS SELECT 客户 ID AS ID, 姓名 AS Name, 地址 AS Address, 城市 AS City FROM Customers ORDER BY ID,Name,Address
结果如下:
这个错误是不是很熟悉?因为很多小伙伴经常喜欢在视图或子查询里面加 ORDER BY,然后一执行就会报这个错。
根本原因不敢妄加断定,因为搜寻了很多文献资料也没给出一个具体的说法。
这里我猜测是因为视图,内联表值函数,派生表 (子查询) 和公用表表达式 (CTE) 等返回的结果还需要进一步的去使用,加了 ORDER BY 进行排序是多此一举,反而会浪费系统资源。所以数据库的开发者不希望大家使用这样不规范操作。
所以下次就不要在表表达式里添加 ORDER BY 了。
五、T-SQL 中表表达式加了 TOP 可以使用 ORDER BY
我们从第四点的报错信息中可以看到:在另外还指定了 TOP、OFFSET 或 FOR XML 是可以使用 ORDER BY 的。
这又是为什么呢?
我们还是先举个栗子给大家看一下
SELECT 客户 ID AS ID, 姓名 AS Name, 地址 AS Address, 城市 AS City FROM (SELECT TOP 3 * FROM Customers ORDER BY 城市
) Customers ORDER BY ID,Name,Address
结果如下:
因为 T -SQL 中带有 ORDER BY 的表表达式加了 TOP 后返回的是一个没有固定顺序的表。因此,在这种情况下,ORDER BY 子句只是为 TOP 选项定义逻辑顺序,就是下面这个逻辑子句
SELECT TOP 3 * FROM Customers ORDER BY 城市
结果如下:
而不保证结果集的排列顺序,因为表表达式外面至少还有一层才是我们最终需要的结果集。
这里的 ORDER BY 只对当前的子查询生效,到了主查询是不起作用的。必须在主查询末尾继续添加一个 ORDER BY 子句才能对结果集生效,就像我们例子中写的那样。
除非逻辑要求,一般情况下并不推荐大家这样巧妙的避开子查询中不能使用 ORDER BY 的限制。
看完上述内容,你们对 ORDER BY 的用法都有哪些有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注丸趣 TV 行业资讯频道,感谢大家的支持。