SQL语句中,为什么group by能够提前"预知"select的别名?

学习Mysql时,遇到了一个很疑惑的地方,查询了资料最终找到了结果:

1.SQL的执行顺序

首先我们知道SQL的执行顺序是:

④ select ① from ② where ③ group by having ⑤ order by ⑥ limit

2.问题出现

group by 支持别名,当我们执行SQL语句:

sql 复制代码
SELECT gender AS xb, COUNT(id) FROM employee GROUP BY xb;

会出现一个很奇怪的现象,按照前面讲述的 SQL 执行顺序,这条 SQL 语句应该报语法错误啊,因为group by是在select之前执行的呀,怎么能提前"预知"别名,似乎有点解释不通了?

3.问题答案

查阅官方文档之后,我发现 having 子句其实是在 select 子句后运行的。也就是说 having 其实是拿着运行 select 后的虚拟表过滤的,而不是原来的表

GROUP BY 子句能够使用SELECT子句中定义的别名,是因为SQL数据库引擎在内部对查询的执行过程进行了优化。这种优化允许引擎在执行GROUP BY之前预先计算SELECT子句中的表达式,并将结果存储为别名。这样,即使在逻辑上GROUP BY应该在SELECT之前执行,引擎也能够识别并重用这些别名,而不是重新计算表达式。

这主要得益于mysql做的拓展,查阅官方文档之后,可以发现是因为 ONLY_FULL_GROUP_BY 这个参数导致的。

开启后(默认开启)
ONLY_FULL_GROUP_BY 是 MySQL 的一种严格 SQL 模式,开启后要求 select、HAVING 和 ORDER BY 中出现的每个非聚合字段,都必须在 GROUP BY 子句中声明,或者能被 GROUP BY 字段唯一决定,否则查询会被拒绝;但 HAVING 子句可以直接引用 select 里的别名。具体网址在下面,感兴趣的可以进一步阅读一下:

dev.mysql.com/doc/refman/...

相关推荐
KellenKellenHao4 小时前
MySQL数据库主从复制
数据库·mysql
一只fish5 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(16)
数据库·mysql
叁沐7 小时前
MySQL 07 行锁功过:怎么减少行锁对性能的影响?
mysql
Java烘焙师7 小时前
架构师必备:业务扩展模式选型
mysql·elasticsearch·架构·hbase·多维度查询
飞翔的佩奇7 小时前
Java项目:基于SSM框架实现的忘忧小区物业管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告】
java·数据库·mysql·vue·毕业设计·ssm框架·小区物业管理系统
@Ryan Ding7 小时前
MySQL主从复制与读写分离概述
android·mysql·adb
feifeigo12314 小时前
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
数据库·mysql·adb
A__tao19 小时前
一键将 SQL 转为 Java 实体类,全面支持 MySQL / PostgreSQL / Oracle!
java·sql·mysql
一只fish20 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(17)
数据库·mysql
叁沐21 小时前
MySQL 06 全局锁和表锁:给表加个字段怎么有这么多阻碍?
mysql