请问在语句执行顺序中,为什么要先执行where再执行group by?
哈哈,又被我看到你了,主要性能问题,给你举个例子
假如数据库有1000w条数据,先group by的话,需要对这1000w数据进行分组;
如果你的where条件为id=1,这时查询出来的结果只有一条数据,再进行group by,实际就是对这1条数据进行分组了,可见大大的提升了执行效率
因为太浪费性能了
执行where语句中尽量的将不符合条件的记录筛选掉,这样可以减少分组的次数
当然要先确定会查询到哪些行,之后才能根据这些行里的数据进行聚合(折叠)
连数据范围都没确定的话,它都不知道要聚合的是什么东西了
如果你已经聚合了,就筛不掉了啊,比如有一列是1、2、3,根据where条件是 要取1和3,如果求和则得4,但是如果先聚合,求和就变成了6,这个时候你难道根据where条件再从6里面把2减掉么?
我这个例子你没看懂么?我再举一个例子:
假设有个表a,有两个字段,有6行记录,如下
TYPE | C |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
1 | 4 |
2 | 3 |
2 | 4 |
按type分组,计算字段c中偶数的平均值,则sql为
select type,avg(c) avg_c from a where c in(2,4) group by type;
得
type | avg_c |
---|---|
1 | 3 |
2 | 4 |
但假设按你说的,先group by ,那么sql为
select type,avg(c) avg_c from a group by type;
得
type | avg_c |
---|---|
1 | 5 |
2 | 3.5 |
然后你拿着这两行数据,怎么用where把聚合前的奇数去掉,来获得和正确sql执行一样的结果??
这个例子中,group by时, 如果不使用avg、sum、max、min等聚合函数对未group by 的字段进行处理,那么这些字段就会直接被舍弃了,group by 时产生了一个新的数据集,行数为group by 后面字段去重的个数,此时已经无法再对原数据进行任何过滤,因为当前阶段已经没有原数据了
因为group by 之后,数据就已经被折叠了,多行变成了一行。下面这两个sql是等效的:
select a,b from c group by a,b;
select distinct a,b from c;
当这个c表里面如果除了a和b以外还有其它字段,如果不聚合,其余字段的数据就会被舍弃,如果聚合,那么只会得到聚合后的结果,找不到聚合之前的数据了