一、当一个查询语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序是:
1.执行where xx对全表数据做筛选,返回第1个结果集。
2.针对第1个结果集使用group by分组,返回第2个结果集。
3.针对第2个结果集中的每1组数据执行select xx,有几组就执行几次,返回第3个结果集。
4.针对第3个结集执行having xx进行筛选,返回第4个结果集。
5.针对第4个结果集排序。
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面(重要)
例子:
完成一个复杂的查询语句,需求如下:
按由高到低的顺序显示个人平均分在70分以上的学生姓名和平均分,为了尽可能地提高平均分,在计算平均分前不包括分数在60分以下的成绩,并且也不计算贱人(jr)的成绩。
分析:
1.要求显示学生姓名和平均分
因此确定第1步select s_name,avg(score) from student
2.计算平均分前不包括分数在60分以下的成绩,并且也不计算贱人(jr)的成绩
因此确定第2步 where score>=60 and s_name!=’jr’
3.显示个人平均分
相同名字的学生(同一个学生)考了多门科目 因此按姓名分组
确定第3步 group by s_name
4.显示个人平均分在70分以上
因此确定第4步 having avg(s_score)>=70
5.按由高到低的顺序
因此确定第5步 order by avg(s_score) desc
使用count(列名)当某列出现null值的时候,count(*)仍然会计算,但是count(列名)不会。
在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优先级别优先于聚合语句(sum,min,max,avg,count)。
简单说来:
where子句:
select sum(num) as rmb from order where id>10
//只有先查询出id大于10的记录才能进行聚合语句
having子句:
select reportsto as manager, count(*) as reports from employees
group by reportsto having count(*) > 4
以northwind库为例.having条件表达示为聚合语句。肯定的说having子句查询过程执行优先级别低于聚合语句。
再换句说话说把上面的having换成where则会出错。统计分组数据时用到聚合语句。
对分组数据再次判断时要用having。如果不用这些关系就不存在使用having。直接使用where就行了。
having就是来弥补where在分组数据判断时的不足。因为where执行优先级别要快于聚合语句。
HAVING子句可以让我们筛选成组后的各组数据.
HAVING子句在聚合后对组记录进行筛选
而WHERE子句在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前
看下面这几个例子吧:
一、显示每个地区的总人口数和总面积.
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
先以region把返回记录分成多个组,这就是GROUP BY的字面含义。分完组后,然后用聚合函数对每组中的不同字段(一或多条记录)作运算。
二、 显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(area)>1000000
在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。
相反,HAVING子句可以让我们筛选成组后的各组数据.
转载于:https://blog.51cto.com/greensky/1047226