一、where和having的区别
where字句在
聚合前
从数据表中的字段直接进行的筛选,也就是说作用在group by字句前。而 having子句在
聚合后
对组记录进行筛选,即对于group by筛选的字段再筛选。
所以类似
where count(*) > 0
这种句子就会报错。因为在where执行的时候,还没有聚合结果。
同样的,
select a, b from table having a = "1"
不会报错,但
select b from table having a = "1"
就会报错,因为select的结果中没有字段a。
二、where和on的区别
select s.* from Student s left join Score sc where s.s_id = sc.s_id;
select s.* from Student s inner join Score sc where s.s_id = sc.s_id;
select s.* from Student s left join Score sc on s.s_id = sc.s_id;
上面几个语句,第2、3句均可以正常执行,第1句会报错。因为left join是会生成一张临时表,再用where去过滤这张表。这张表里面会有左表的所有行,即使在右表中没有匹配的行,因此如果用where去过滤这张表,sc.s_id可能不存在。但改成on则不会有这种问题,因为on操作会把右表不存在的sc.s_id补成NULL。inner join用where也不会报错,因为inner join只会出现两边都有记录的行。
三、select语句的常见顺序
一般来说都是
select...where...group by...having
,因为mysql也是从左往右执行。如果改变顺序,如换成
select...group by...where...
则会报错。