目录
聚集函数
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。使用这种类型的函数用来检索数据,以便分析和报表生成。这种类型的检索例子用以下几种:
- 确定表中的行数(或者满足某个条件或包含某个特定值的函数);
- 获取表中行组的和;
- 找出表列(或所有行或者某些特定的行)的最大值、最小值和平均值。
函数 说明 AVG() 返回某列的平均值 COUNT() 返回某列的函数 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列之和 注意:
-
AVG()只能用来确定特定数值列的平均值,为了获得多个列的平均值,必须使用多个AVG()处理;
-
使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值还是非空值;使用COUNT(column)对特定列中具有具体值的行进行计数,忽略NULL值;
分组数据
GROUP BY
-
GROUP BY子句可以包含任意数目的列;
-
如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总;
-
GROUP BY子句中列出的每个列都必须是检索列或有效的表达式;
-
除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出;
-
如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,他们将分为一组;
-
GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前;
-
使用WITH ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出所有记录的总和,及统计记录数量。
ORDER BY 与 GROUP BY的差别
ORDER BY | GROUP BY |
排序产生输出 | 分组行。但输出可能不是分组的顺序 |
任意列都可以使用 | 只可能使用选择列或表达式列,而且必须使用每个选择列的表达式 |
不一定需要 | 如果与聚集函数一起使用列(表达式),则必须使用 |
HAVING
使用条件:
- 行已经被分组;
- 使用了聚合函数;
- 满足HAVING子句中条件的分组将被显示;
- HAVING不能单独使用,必须和GROUP BY一起使用。
注:不能在WHERE子句中使用聚合函数。
WHERE和HAVING的对比
区别1:WHERE可以直接使用表中的字段作为筛选条件,但是不能使用分组中的计算函数作为筛选条件;HAVING必须要与GROUP BY配合使用,可以把分组计算的函数和分组字段作为筛选条件。
区别2:如果需要通过连接从关联表中获取需要的数据,WHERE是先筛选后连接,而HAVING是先连接后筛选。
优点 | 缺点 | |
WHERE | 先筛选数据再关联,执行效率高 | 不能使用分组中的计算函数进行筛选 |
HAVING | 可以使用分组中的计算函数 | 在最后的结果集中进行筛选,执行效率较低 |
SELECT的执行过程
查询的结构
#方式1
SELECT...,...,...
FROM ...,...,
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ....,....
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
#方式2
SELECT...,...,...
FROM ...JOIN...
ON 多表的连接条件
JOIN ...
ON ...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ....,....
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMIT ...,...
SELECT执行顺序
1、关键词顺序
SELECT...FROM...WHERE...GROUP BY...HAVING...ORDER BY...LIMIT...
2、SELECT语句的执行顺序
FROM->WHERE->GROUP BY->HAVING->SELECT的字段->DISTINCT->ORDER BY->LIMIT
SQL执行原理
SELECT是先执行FROM这一步的。在这结算,如果是多表联查,还会经历下面的几个步骤:
1、首先先通过CROSS JOIN求笛卡尔积,相当于得到虚拟表vt1-1;
2、通过ON进行筛选,在虚拟表vt1-1的基础上进行筛选,得到虚拟表vt1-2;
3、添加外部行。如果我们使用的是左连接、右连接或者全连接,就会涉及到外部行,也就是在虚拟表vt1-2的基础上增加外部行,得到虚拟表vt1-3。