学习Mysql时,遇到了一个初学者都很疑惑的地方:
1、首先我们知道SQL的执行顺序是:④ select① from② where③ group by having⑤ order by
⑥ limit
2、我们知道group by 支持select别名,当我们执行SQL语句:
SELECT gender AS xb, COUNT(id) FROM employee GROUP BY xb;
大家都发现了一个很奇怪的现象,按照前面讲述的执行顺序,这条SQL语句应该报语法错误啊,因为group by是在select之前执行的呀,怎么能提前“预知”别名,似乎有点解释不通了。
3、经过试验,我发现having子句是在select子句后运行的,也就是说having是拿着select后的虚拟表过滤的。不是原来的表。
4、结论:
GROUP BY 子句能够使用SELECT子句中定义的别名,是因为SQL数据库引擎在内部对查询的执行过程进行了优化。这种优化允许引擎在执行GROUP BY之前预先计算SELECT子句中的表达式,并将结果存储为别名。这样,即使在逻辑上GROUP BY应该在SELECT之前执行,引擎也能够识别并重用这些别名,而不是重新计算表达式。
这主要得益于mysql做的拓展,经过查找mysql文档,发现是因为ONLY_FULL_GROUP_BY这个参数导致的。具体网址在下面,感兴趣的可以阅读一下:
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_only_full_group_by
测试所用表结构:
create table test( id int auto_increment comment 'id' primary key , name varchar(50) not null comment '姓名', gender char(1) comment '性别' )comment '测试表 ';