where子句与having短语的区别在于作用对象不同。where子句作用于基础表或视图,从中选择满足条件的元组,而由于聚集函数是对选择之后的目标行进行计算的,所以where子句不能包含聚集函数;having短语作用于组,从中选择满足条件的组。
where子句在group by语句之前;sql会在分组之前计算where子句。
having子句在group by语句之后;sql会在分组之后计算having子句。
执行的顺序 :where>group by>聚合语句(sum、count、avg、max、min)>having子句
下面通过案例来进行分析
首先我们准备一个部门人员工资表
SET FOREIGN_KEY_CHECKS=0;
#建表
DROP TABLE IF EXISTS `salary_info`;
CREATE TABLE `salary_info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`department` varchar(16) NOT NULL DEFAULT '',
`name` varchar(16) NOT NULL DEFAULT '',
`salary` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
# 插入部分数据
INSERT INTO `salary_info` VALUES ('1', '产品', 'pro1', '100');
INSERT INTO `salary_info` VALUES ('2', '产品', 'pro3', '50');
INSERT INTO `salary_info` VALUES ('3', '产品', 'pro2', '90');
INSERT INTO `salary_info` VALUES ('4', '开发', 'eng1', '70');
INSERT INTO `salary_info` VALUES ('5', '开发', 'eng2', '80');
INSERT INTO `salary_info` VALUES ('6', '测试', 'tes1', '86');
查询1: 要查找平均工资大于80的部门
select department, AVG(salary) from salary_info
GROUP BY department
having AVG(salary) > 80
查询1结果
查询1中, 先通过groupby进行分组,然后执行avg将分组中的记录进行结果计算,最终返回查询结果
查询2: 查询测试部门的人员数量
# 方法1
select department, count(1) from salary_info
GROUP BY department
HAVING department = '测试'
# 方法2
select department, count(1) from salary_info
where department = '测试'
GROUP BY department
查询2结果
查询2中,有两个方案, 方法1是先查询出每个部门的人员个数,然后通过having来对组的查询结果进行筛选, 方法2是先查询数据所有的测试部门人员,然后对测试人员进行groupby,并通过count进行求和
注意,where一定在groupby前面执行,否则会报error错误
网友评论