当前位置: 首页 > 科技观察

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

时间:2023-03-23 09:52:26 科技观察

小伙伴们在进行SQL排序的时候可以很自然的使用ORDERBY。无论是默认ASC的升序还是DESC的降序,几乎都唾手可得。今天给大家分享一些你可能不知道的ORDERBY的用法。1.ORDERBY返回游标而不是集合。SQL的理论其实就是集合论。数据的相交、并集和差异等常见问题可以使用集合思维来解决。集合中的行之间没有预先定义的顺序,它只是成员的逻辑组合,成员之间的顺序无关紧要。如下图所示,每个括号内的内容是一条记录,在排序之前,它们是随机分布在集合中的。Student(ID,Name,Age)Studentcollection但是对于带有排序效果的ORDERBY子句的查询,它返回一个对象,其中的行按照特定的顺序组织在一起。我们称这个对象为游标。如下图,对Student表的ID进行ORDERBY排序后,Student表就变成了一个有序的对象,也就是我们上面说的游标。Student(ID,Name,Age)学生对象2.ORDERBY子句是唯一可以重用列别名的步骤。注意:markdown对于代码块的语法是在开始和结束行都加上:```,其中`是windows键盘的左上角,涉及到SQL语句的语法顺序和执行顺序。我们常见的SQL语法顺序如下:SELECTDISTINCTFROM[left_table]JOINONWHEREGROUPBYWITHHAVINGORDERBY并且数据库引擎不是从SELECT而是从FROM执行SQL语句。具体执行顺序如下(关键字前面的数字代表SQL执行步骤顺序):(8)SELECT(9)DISTINCT(11)(1)FROM[left_table](3)JOIN(2)ON(4)WHERE(5)GROUPBY(6)WITH(7)HAVING(10)ORDERBY从上面可以看出,SELECT是在HAVING之后执行的。此时,SELECT之后的列的别名只对后面的步骤有效,而对SELECT之前的步骤无效。所以如果在WHERE、GROUPBY或HAVING之后使用列别名,就会报错。让我们用一个例子来测试它。示例表Customers的结构和数据如下:1.WHERE后不使用别名时,SELECTnameASName,addressASAddress,cityASCityFROMCustomersWHEREcity='Guangzhou'结果如下:2.使用列别名时在WHERE之后,SELECTnameASName,addressASAddress,cityASCityFROMCustomersWHERECity='Guangzhou'的执行结果如下:从返回信息中可以看出改名后的City无法被WHERE识别,所以提示“columnname'City'无效”将被报告。您也可以使用上述方法测试其他关键字。接下来,我们在GROUPBY和HAVING之后测试列别名的使用。3.测试GROUPBY后,使用列别名SELECTcityASCityFROMCustomersGROUPBYCity结果如下:4.测试HAVING后,使用列别名SELECTcityASCityFROMCustomersGROUPBYcityHAVINGCOUNT(City)>1结果如下:5.之后测试ORDERBY,使用列别名SELECTnameASName,addressASAddress,CityASCityFROMCustomersORDERBYCity结果如下:从上面几个测试例子的结果来看,我们的结论是正确的:ORDERBY子句是唯一的步骤可以重用列别名。3.谨慎使用数字后跟ORDERBY的方式进行排序。有些朋友为了省事喜欢在ORDERBY后面写数字。具体例子如下:SELECTnameASName,addressASAddress,cityASCityFROMCustomersORDERBY1,2,3结果如下:写入的结果对于当前查询是正确的。ORDERBY后的数字1、2、3分别代表SELECT后的第1、2、3个字段(即Name、Address、City)。但是当查询列发生变化时,忘记修改ORDERBY列表。尤其是当查询语句很长的时候,会很难在SELECT列表中找到ORDERBY对应的列。例如:SELECTcustomerIDASID,nameASName,addressASAddress,cityASCityFROMCustomersORDERBY1,2,3由于增加了一列“客户ID”,本题的意思还是排序Name,Address,City,但是因为使用ORDERBY加数字,排序最终结果如下:结果不是我们想要的,所以请使用带数字的ORDERBY,尽量使用带列名或列别名的ORDERBY。4、表达式不能使用ORDERBY排序表表达式包括视图、内联表值函数、派生表(子查询)和公用表表达式(CTE)。例如下面的视图是无效的CREATEVIEWV_CustomersASSELECT客户IDASID,nameASName,addressASAddress,cityASCityFROMCustomersORDERBYID,Name,Address结果如下:这个错误是不是很眼熟?因为很多小伙伴经常喜欢在视图或者子查询中加上ORDERBY,然后一执行就会报这个错。根本原因不敢妄下判断,因为查了很多文献,没有给出具体的说法。这里我猜测是因为视图、内联表值函数、派生表(子查询)和公用表表达式(CTE)返回的结果需要进一步使用。添加ORDERBY进行排序是多余且浪费系统资源的。所以,数据库开发者不希望大家使用这种不规范的操作。所以下次不要在表表达式中加入ORDERBY。5、T-SQL中表表达式加TOP可以使用ORDERBY从第四点的报错信息可以看出:另外,ORDERBY可以使用TOP、OFFSET或FORXML。这就是为什么?先给大家举个栗子给大家看下SELECTcustomerIDASID,nameASName,addressASAddress,cityASCityFROM(SELECTTOP3*FROMCustomersORDERBYcity)CustomersORDERBYID,Name,Address的结果如下:因为T-SQL中带ORDERBY的表表达式添加TOP后返回的是一张没有固定顺序的表。因此,在这种情况下,ORDERBY子句只是定义了TOP选项的逻辑顺序,即后面的逻辑子句SELECTTOP3*FROMCustomersORDERBYcity的结果如下:不保证结果集的顺序,因为表表达式外至少有一层,就是我们最终需要的结果集。这里的ORDERBY只对当前子查询有效,对主查询无效。您必须继续在主查询的末尾添加ORDERBY子句才能对结果集生效,就像我们在示例中所写的那样。除非逻辑需要,否则一般不建议你巧妙地规避子查询中不能使用ORDERBY的限制。以上就是ORDERBY的一些用法,你学会了吗?如有不明白或有疑问,请在下方留言。