专栏/order by 的高级用法

order by 的高级用法

2023年11月24日 09:23--浏览 · --点赞 · --评论
gzqhero
粉丝:2.5万文章:155

小伙伴们在进行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子句是唯一能重用列别名的一步

这里涉及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后面不使用别名的情况


结果如下:

图片


2、WHERE后面使用列别名的情况


执行结果如下:

图片


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


其他关键字大家也可以使用上述方法进行测试,下面我们测试GROUP BY和HAVING后面使用列别名的情况。


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


结果如下:

图片


4、测试HAVING后使用列别名



结果如下:

图片


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



结果如下:

图片


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


三、谨慎使用ORDER BY 后面接数字的方式来进行排序

有些小伙伴为了图省事,喜欢在ORDER BY后面写数字,具体示例如下:



结果如下:

图片

这样写的结果,针对当前的查询是正确没有问题的,ORDER BY后面的数字1,2,3分别代表SELECT后面的第1,第2,第3个字段(也就是Name,Address,City)。
可是当查询的列发生改变,忘了修改ORDER BY列表。特别是当查询语句很长时,要找到ORDER BY与SELECT列表中的哪个列相对应会非常困难。


例如



由于增加了一列“客户ID”,原本的题意还是对Name,Address,City排序,但是因为使用了ORDER BY加数字,排序后的结果如下:

图片

得到的结果并不是我们想要的,所以请慎用ORDER BY加数字,尽量使用ORDER BY加列名或列别名


四、表表达式不能使用ORDER BY排序表表达式包括视图,内联表值函数,派生表(子查询)和公用表表达式(CTE)。例如下面的视图是无效的

结果如下:

图片


这个错误是不是很熟悉?因为很多小伙伴经常喜欢在视图或子查询里面加ORDER BY,然后一执行就会报这个错。


根本原因不敢妄加断定,因为搜寻了很多文献资料也没给出一个具体的说法。
这里我猜测是因为视图,内联表值函数,派生表(子查询)和公用表表达式(CTE)等返回的结果还需要进一步的去使用,加了ORDER BY进行排序是多此一举,反而会浪费系统资源。所以数据库的开发者不希望大家使用这样不规范操作。


所以下次就不要在表表达式里添加ORDER BY了。


五、T-SQL中表表达式加了TOP可以使用ORDER BY我们从第四点的报错信息中可以看到:在另外还指定了 TOP、OFFSET 或 FOR XML是可以使用ORDER BY的。

图片

这又是为什么呢?

我们还是先举个栗子给大家看一下


结果如下:

图片


因为T-SQL中带有ORDER BY的表表达式加了TOP后返回的是一个没有固定顺序的表。因此,在这种情况下,ORDER BY子句只是为TOP选项定义逻辑顺序,就是下面这个逻辑子句


结果如下:

图片


而不保证结果集的排列顺序,因为表表达式外面至少还有一层才是我们最终需要的结果集。


这里的ORDER BY只对当前的子查询生效,到了主查询是不起作用的。必须在主查询末尾继续添加一个ORDER BY子句才能对结果集生效,就像我们例子中写的那样。


除非逻辑要求,一般情况下并不推荐大家这样巧妙的避开子查询中不能使用ORDER BY的限制




投诉或建议

玻璃钢生产厂家常州衢州玻璃钢雕塑供货商玻璃钢浮雕雕塑厂吉安商场美陈个性熊猫玻璃钢雕塑商洛玻璃钢长颈雕塑东营仿铜玻璃钢雕塑制作玻璃钢雕塑女通辽小品系列玻璃钢雕塑制作白城玻璃钢雕塑定制商场美陈的灯是接多少伏电源玻璃钢天马行空雕塑西安精巧玻璃钢座椅雕塑阳江玻璃钢雕塑厂家现货安阳玻璃钢雕塑厂家地址玻璃钢童话雕塑玻璃钢雕塑的制模师商场主题街区美陈广西玻璃钢人物雕塑定制价格网格玻璃钢雕塑玻璃钢树池雕塑玻璃钢剪纸雕塑怎样制作吉林水果玻璃钢雕塑供应商艺术商场美陈哪家好户外玻璃钢人物雕塑要求长春玻璃钢景观雕塑广州定制玻璃钢雕塑优势南京秦淮商场美陈玻璃钢树脂抽象雕塑商场美陈室外装置政府报批广西耐用性高玻璃钢雕塑厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化