导读为什么只有ORDER BY后面可以使用列别名

为什么不推荐使用ORDER BY后接数字来排序

为什么视图和子查询里面不能使用ORDER BY

……

​小伙伴们在进行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

FROM [left_table]

JOIN

ON

WHERE

GROUP BY

WITH

HAVING

ORDER BY

而数据库引擎在执行SQL语句并不是从SELECT开始执行,而是从FROM开始,具体执行顺序如下(关键字前面的数字代表SQL执行的顺序步骤):

(8)SELECT (9)DISTINCT (11)

(1)FROM [left_table]

(3) JOIN

(2) ON

(4)WHERE

(5)GROUP BY

(6)WITH

(7)HAVING

(10)ORDER BY

从上面可以看到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

结果如下:

注意:本文是以标准SQL来测试的,MySQL的HAVING 能使用列别名,是因为对此做了扩展,必须开启ONLY_FULL_GROUP_BY才可以。

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

觉得不错,记得帮忙点个赞,谢谢啦~

mysql 别名排序没效果_除了会排序,你对ORDER BY的用法可能一无所知!相关推荐

  1. mysql组合索引没效果的原因

    1.联合索引失效的条件 联合索引又叫复合索引.两个或更多个列上的索引被称作复合索引. 对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引 ...

  2. javafx 动画没效果_通过JavaFX标注制作动画效果

    javafx 动画没效果 在本文中,您将学习如何使用JavaFX的动画API创建标注. 您可以在https://www.youtube.com/watch?v=XTHbB0LRdT4的 YouTube ...

  3. 排序字段设计_内容搜索排序表达式的最佳实践

    简介:本文重点介绍"开放搜索"中的排序表达式的配置及特征性函数的应用 某新闻资讯平台,在内容搜索场景中需要满足业务多样化,个性化的需求,在query改写配置好后,希望在排序阶段进行 ...

  4. JAVA十大排序算法动画_十大排序算法(java实现)

    [前言]最近在重新研究算法,此篇博文供自己复习使用也为方便广大程序员同学!此文代码均为自己实现,通过对比经典解法校验,若有错请读者及时提出! - [对比分析图]首先,我们先来对比分析一下这十大排序算法 ...

  5. devc代码补全没效果_从零开始写文本编辑器(二十八):自动补全(上)

    前言 我本没打算这么早就写"自动补全"功能的. 但是在写XML资源编辑时,为了实现自动引用已有资源@string/xxx,需要一个合适的列表来让我选择.这样能防止拼写错误. 也就是 ...

  6. redis配置主从没效果_跟我一起学Redis之加个哨兵让主从复制更加高可用

    Redis哨兵(Sentinel)其实本质就是一个RedisServer节点,通过设置 运行模式 来开启哨兵的功能:主要功能如下: 监控(Monitoring ):哨兵节点会不断地检查的主服务和从服务 ...

  7. hexo部署成功但是没效果_使用 Hexo+GitHub 搭建个人免费博客教程(小白向)

    前言 近些年来很多用户都喜欢使用 GitHub Pages 来搭建 Hexo 静态博客网站,其最吸引人的莫过于完全免费使用,并且非常稳定. 虽然搭建时比较麻烦,有点折腾,但是配置完成后,基本不需要操心 ...

  8. mysql pdo 插入没效果_MySQL分库分表后用PHP如何来完美操作

    当单表达到几千万时,查询一次要很久,如果有联合查询,有可能会死在那 分库分表主要就是解决这个问题,减小数据库的负担,缩短查询时间分库 1)按功能分 用户类库.商品类库.订单类库.日志类.统计类库... ...

  9. Mysql 启动失败没日志_小记一次mysql启动失败没有日志的处理

    本来mysql好的,之前清理了一次tmp下的东西,mysql在查询的时候提示: Can't create/write to file'/tmp/ib0n3frL 然后停止启动: [root@sevck ...

最新文章

  1. UA MATH566 统计理论4 贝叶斯统计基础1
  2. 在 linux 下使用 CMake 构建应用程序
  3. Oracle 数字与空值的排序问题
  4. Vue — 第七天(vue-cli-案例)
  5. Javascript基础 对象与方法的识别
  6. c语言第八章函数程序设计,C语言程序设计-第八章 函数.ppt
  7. Spring Ioc Configration - Annotation
  8. BXP_4.1安装配置及域应用随记一
  9. Struts2-03-拦截器(BOS物流项目用户登录拦截)
  10. 一款舒适的画图软件,支持各种文件格式的导入和导出,Edraw Max 包含中文版和英文版,也包含 Mac 版本 和 Windows 版本
  11. rational rose的下载和安装教程
  12. 一招解决网页文字无法复制
  13. HTML页面基本结构
  14. 2022年字节跳动日常实习面经(抖音)
  15. 前端弹出对话框 js实现 ajax交互
  16. linux系统编程实训总结,linux实训总结与体会
  17. Windows下C++调用系统软键盘及其需要注意的点
  18. 基于物联网的无线温度系统在钢铁行业的应用
  19. 微信聊天记录如何恢复
  20. 学生成绩排名 (用结构体数组按成绩排名)

热门文章

  1. 学计算机硬盘电脑多大好,笔记本电脑固态硬盘要多大的合适
  2. 北斗通讯协议4.0 java_北斗4.0协议讲解.doc
  3. 好用的chrome的插件
  4. Docker基于现有镜像构建新镜像
  5. 【基于Simulink+UG NX MCD 一级倒立摆控制系统仿真】建模和分析(一)
  6. Fortran编程(VScode配置)——笔记2
  7. fortran语言快速学习
  8. 2022-2028全球多通道光纤旋转接头(FORJ)行业调研及趋势分析报告
  9. day02 软考习题理解
  10. matlab 动态图只能显示等平面吗,matlab平面浓度图