除了会排序,你对ORDER BY的用法可能一无所知!

 

 

文章来源: SQL数据库开发数据库

做者:丶平凡世界函数

 

导读测试

  • 为何只有ORDER  BY后面可使用列别名
  • 为何不推荐使用ORDER BY后接数字来排序
  • 为何视图和子查询里面不能使用ORDER BY

    ……3d

 

小伙伴们在进行SQL排序时,都能很天然的使用到ORDER BY。不论是默认ASC的升序,仍是DESC降序,几乎都是信手拈来。code

 

今天给你们分享一些你可能不知道的ORDER BY用法。对象

 

 

1、ORDER BY返回的是游标而不是集合blog

SQL的理论实际上是集合论,常见的相似求数据的交集、并集、差集均可以使用集合的思惟来求解。排序

 

集合中的行之间没有预先定义的顺序,它只是成员的一种逻辑组合,成员之间的顺序可有可无。资源

 

以下图,每个括号里的内容就是一条记录,在没排序前,他们都是随机分布在集合中。开发

 

Student(ID,Name,Age)

Student集合

 

可是对于带有排序做用的ORDER BY子句的查询,它返回的是一个对象,其中的行按特定的顺序组织在一块儿,咱们把这种对象称为游标。

 

以下图,通过对Student表的ID进行ORDER BY排序后,Student表变成了有序对象,也就是咱们上面说的游标。

 

Student(ID,Name,Age)

Student对象

 

 

 

2、ORDER BY子句是惟一能重用列别名的一步

这里涉及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结构及数据以下:

 

一、WHERE后面不使用别名的状况

 

SELECT 
姓名 AS Name,
地址 AS Address,
城市 AS City
FROM Customers
WHERE 城市='广州'

结果以下:

 

二、WHERE后面使用列别名的状况

SELECT 
姓名 AS Name,
地址 AS Address,
城市 AS City
FROM Customers
WHERE City='广州'

 

执行结果以下:

 

从返回的消息中咱们能够看到,重命名后的City并不能被WHERE识别,因此才会报“列名'City'无效”的提示。

 

 

 

其余关键字你们也可使用上述方法进行测试,下面咱们测试GROUP BY和HAVING后面使用列别名的状况。

 

三、测试GROUP BY后使用列别名

SELECT 
城市 AS City
FROM Customers
GROUP BY City

 

结果以下:

 

四、测试HAVING后使用列别名

 

SELECT 
城市 AS City
FROM Customers
GROUP BY 城市
HAVING COUNT(City)>1

 

结果以下:

 

五、测试ORDER BY后面使用列别名

 

SELECT 
姓名 AS Name,
地址 AS Address,
城市 AS City
FROM Customers
ORDER BY City

 

结果以下:

 

从上面的几个测试示例的结果中,能够得出咱们的结论是正确的:ORDER BY子句是惟一能重用列别名的一步。

 

 

3、谨慎使用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加列名或列别名

 

4、表表达式不能使用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了。

 

 

5、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的一些用法,你学会了吗?有不明白或疑问的地方,欢迎在底下留言。

 

原文连接:https://mp.weixin.qq.com/s/5iv1z6SCf0nMyIEWavlyRQ