先创建一个数据表 access_log
aid | site_id | count | date |
---|---|---|---|
1 | 1 | 45 | 2016-05-10 |
2 | 3 | 100 | 2016-05-13 |
3 | 1 | 230 | 2016-05-14 |
4 | 2 | 10 | 2016-05-14 |
5 | 5 | 205 | 2016-05-14 |
6 | 4 | 13 | 2016-05-15 |
7 | 3 | 220 | 2016-05-15 |
8 | 5 | 545 | 2016-05-16 |
9 | 3 | 201 | 2016-05-17 |
GROUP BY 语句
GROUP BY
语句根据一个或多个列对结果集进行分组。在分组的列上可以使用 COUNT、SUM、AVG 等函数。
1 | select col_name, fun(col_name) from table_name |
实例演示
统计 access_log 中各 site 的访问量
1 | select site_id, sum(access_log.count) as nums from access_log |
site_id | count |
---|---|
1 | 275 |
2 | 10 |
3 | 521 |
4 | 13 |
5 | 750 |
使用 WITH ROLLUP
WITH ROLLUP
可以实现在分组统计数据基础上再进行相同的统计(SUM、AVG、COUNT 等)
1 | select site_id, sum(access_log.count) as nums from access_log |
site_id | nums |
---|---|
1 | 275 |
2 | 10 |
3 | 521 |
4 | 13 |
5 | 750 |
NULL | 1571 |
其中 NULL 表示所有 site_id 的 count 的总和。
可以使用 coalesce(a,b,c)
来设置一个取代 NULL 的名称
如果a == null,则选择b;
如果b == null,则选择c;
如果a != null,则选择a;
如果a b c 都为 null ,则返回为 null。
1 | select coalesce(site_id, '总访问量'), sum(access_log.count) as nums from access_log |
site_id | nums |
---|---|
1 | 275 |
2 | 10 |
3 | 521 |
4 | 13 |
5 | 750 |
总访问量 | 1571 |
HAVING 子句
HAVING
语句通常与 GROUP BY
语句联合使用,用来筛选由 GROUP BY
语句返回的记录集。
1 | select col_name, fun(col_name) from table_name |
HAVING
语句的存在弥补了 WHERE
关键字不能与聚合函数联合使用的不足。
实例
查询 access_log 表中 site_id 小于 4 且总访问量大于 200 的数据:
1 | select site_id, sum(access_log.count) as nums from access_log |
site_id | nums |
---|---|
1 | 275 |
3 | 521 |
查询语句执行顺序
一个查询语句同时出现了 WHERE
、GROUP BY
、HAVING
等语句的时候,执行顺序是:
- FROM <left_table>
- ON <join_conditon>(关联条件)
- JOIN <right_table>
- WHERE <where_conditon>(筛选条件)
- GROUP BY <col_name>(分组)
- 聚合函数(col_name)(having 子句中的)
- HAVING <where_conditon>(分组后筛选条件)
- SELECT
- DISTINCT(去重)
- UNION(合并)
- ORDER BY(排序)
- LIMIT(截取)
根据以上的顺序,将查询语句分为大致三个顺序:
表拼接(1 ~ 3)
先加载左表,再判断关联条件,加载右表。
先筛后选(4 ~ 8)
一句话总结:先根据条件语句先后筛选数据,再选择指定的字段。
条件语句的执行顺序依次是 WHERE
、GROUP BY
、HAVING
,这恰好是它们在 SQL
语句中的先后顺序。若 HAVING
中有聚合函数,则先执行聚合函数再执行 HAVING
筛选后,再通过 SELECT
语句查找指定字段
无条件筛选(9 ~ 12)
最后剩下的子句都是没有条件的筛选语句。
这样可以保证效率最高,比如如果在前面排序,显然会对无关的数据进行排序,降低效率。
依次是:去重、合并、排序、范围截取