mysql中having 与where 的异同点

DATE: 2016-11-10 / VIEWS: 655

[开门见山先总结两点]
[1]having与where类似,可以筛选数据,where后的表达式怎么写,having后就怎么写
[2]能用where的地方 也能用having ,用haveing的地上 不一定能用where
[实例一]
话说有一个学生成绩表(score),结构如下:
id(记录编号) sid(学生id) chinese(语文成绩) maths(数学成绩) english(英语成绩)
现在有一个需求是:找出语文成绩和数学成绩相差超过30分的同学(教育界称此现象为“偏科”)
Select sid,maths,chinese,ABS(chinese-maths) AS bk FROM score Where bk>30
mysql返回:Unknown column 'bk' in 'where clause';告诉我们,这样做不可行.
若把where改成having呢?
Select sid,maths,chinese,ABS(chinese-maths) AS bk FROM score HAVING bk>30
可喜可贺,成功返回记录集结果如下:

如果,不想用having怎么办呢?
Select sid,maths,chinese,ABS(chinese-maths) AS bk FROM score Where ABS(chinese-maths)>30
可喜可贺,成功返回记录集结果如下,和使用having达到了一样的效果。


听民间传言,据权威的说法是:
where针对表中的列发挥作用,查询数据
having是对查询结果中得到的列发挥作用,筛选数据(也就是说从查询出的结果集再次进行筛选)

为了更好的理解这句话,来一个where与having并用的sql来体验一下;请继续往下读.
[实例二]
话说有一个学生表(student)结构如下:
id(学生编号) name(姓名) sex(性别)
需求又来了,现在要得到.在数学成绩及格的前提下;计算出男,女的数学平均分各是多少
Select sex,AVG(maths) AS avgmaths FROM student,score Where student.id= score.sid AND maths>=60 GROUP BY sex
返回记录集如下:

得到了,男生的数学平均分为89.3333;女生的平均分为77.3333(国际惯例,数学当然是男生学的好喽!)
在以上原有需求再加一条,分组后平均分超过80分才显示
Select sex,AVG(maths) AS avgmaths FROM student,score Where student.id= score.sid AND maths>=60 AND avgmaths > 80 GROUP BY sex
mysql返回:Unknown column 'avgmaths' in 'where clause'
跟据上面的说话可以解释为:where是对表中的列发挥作用,avgmaths并非是表中的原有的列,所以失败了.
Select sex,AVG(maths) AS avgmaths FROM student,score Where student.id= score.sid AND maths>=60 GROUP BY sex HAVING avgmaths>80
成功返回记录:

haveing是对查询结果中得到的列(avgmaths)发挥作用,又进行了一次筛选。所以成功得到,所需记录。