1.先回顾下基础知识:函数
Group By 对数据分组聚合,经常伴随having使用。having能够处理单记录,也能够小组为单位处理。spa
语句:code
SELECT col
FROM table
[WHERE]
[GROUP BY]
[HAVING]
[ORDER BY [ASC]|[DESC]]blog
1.FROM子句生成数据集
2.WHERE子句过滤1生成的数据集
3.GROUP BY子句聚合2生成的数据集
4.HAVING子句过滤3生成的数据集
5.SELECT子句在4的结果上作些转换
6.ORDER BY子句对5变换后的数据集进行排序排序
在SELECT子句但不在GROUP BY子句中的字段必须使用聚合函数。
聚合函数是对一组值执行计算并返回单个值得肯定性函数,如COUNT,SUM,AVG,MIN,MAX,VAR_POP,VAR_SAMP等。ci
2.正文:it
从SQL-92标准开始,强制规定了GROUP BY子句的使用,主流厂家也多数已经遵照,即:SELECT的字段,要么在GROUP BY中已经列出,要么使用了聚合函数。table
如:有user表,order表,想看每一个用户的消费状况,即按userid查询order分组数据,咱们真正想要的是: class
SELECT u.userid,u.username,u.city,SUM(o.OrderTatal) AS total FROM user u LEFT JOIN order o ON u.userid=o.userid GROUP BY u.userid
但不幸,这条语句不符合GROUP BY要求,必须把SELECT中出现,但没使用聚合函数的字段u.username,u.city加入到GROUP BY 子句中,咱们其实不关心是否对这2个字段聚合,聚合这2字段对咱们指望的结果意义也不大,但不写会报错,因而一般会写成:基础
SELECT u.userid,u.username,u.city,SUM(o.OrderTatal) AS total FROM user u LEFT JOIN order o ON u.userid=o.userid GROUP BY u.userid,u.username,u.city
这种列称为功能依赖列,这样写也知足了要求,但一个不足是咱们真正关心的汇总条件被淹没了。若是时间隔得久一点或是语句复杂一点,你有把握区分出实际上是多余的功能依赖列吗?咱们要按每一个user汇总,也要区分具体city?有时你不得不去了解整个查询的基础。
改进这种类型的GROUP BY,不要让真正关心的汇总条件被淹没。改进后的语句:
SELECT u.userid,u.username,u.city,o.total FROM user u LEFT JOIN (SELECT t.userid,SUM(t.OrderTotal) AS Total FROM Order AS t GROUP BY t.userid) AS o ON u.userid=o.userid;