分组与聚集
使用GROUP来完成分组的功能,如下图所示:
 1
2
3
4
5
6
7
8
9
10
11
12
  | mysql> SELECT open_emp_id
    -> FROM account
    -> GROUP BY open_emp_id;
+-------------+
| open_emp_id |
+-------------+
|           1 |
|          10 |
|          13 |
|          16 |
+-------------+
4 rows in set (0.00 sec)
  | 
  
COUNT()称为聚集函数,可以计算每个分组的行数,如下面的例子所示。本例相对于上例来说仅仅添加了COUNT()函数来完成聚集功能。
 1
2
3
4
5
6
7
8
9
10
11
12
  | mysql> SELECT open_emp_id, COUNT(*) how_many
    -> FROM account
    -> GROUP BY open_emp_id;
+-------------+----------+
| open_emp_id | how_many |
+-------------+----------+
|           1 |        8 |
|          10 |        7 |
|          13 |        3 |
|          16 |        6 |
+-------------+----------+
4 rows in set (0.00 sec)
  | 
  
上例说明,通过联合使用group by子句和count()聚集函数,可以在不查看原始数据的情况下,精确满足业务问题对数据的需要。
使用group函数时,不应该在WHERE子句中使用聚集函数COUNT()。因为在评估WHERE子句时分组还没有被创建。因此必须在HAVING()子句中使用分组过滤条件。
 1
2
3
4
5
6
7
8
9
10
11
12
  | mysql> SELECT open_emp_id, COUNT(*) how_many
    -> FROM account
    -> GROUP BY open_emp_id
    -> HAVING COUNT(*) > 4;
+-------------+----------+
| open_emp_id | how_many |
+-------------+----------+
|           1 |        8 |
|          10 |        7 |
|          16 |        6 |
+-------------+----------+
3 rows in set (0.00 sec)
  | 
  
聚集函数
聚集函数对某个分组的所有行执行特定的操作。
MAX()返回集合中的最大值 
MIN()返回集合中的最小值 
AVG()返回集合中的平均值 
SUM()返回集合中的所有值的和 
COUNT()返回集合中值的个数 
隐式分组或显示分组
隐式分组就是没有使用GOURP BY的查询语句,显示分组即是使用了GROUP BY子句的语句。
对独立值计数
即在COUNT()子句中不是使用COUNT(*)来进行聚集,而是使用COUNT(name)来记数。当需要去除重复的name时,需要在COUNT()中添加DISTINCT关键字。即COUNT(DISTINCT NAME)的方式来完成对应的计数统计。
使用表达式
在聚集函数中可以使用表达式
NULL值的处理
对于MAX(),MIN(),AVG(),SUM()中,没有什么影响。但是对于COUNT()而言,当使用COUNT(*)时,会有变化。但是使用COUNT(NAME)这种情况没有变化。
产生分组
单列分组
GROUP BY后面仅仅有一个条目
多列分组
GROUP BY后面有多个条目
利用表达式分组
GROUP BY后面跟着的是一个表达式
产生合计数
使用WITH ROLLUP,示例如下:
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  | mysql> SELECT product_cd, open_branch_id,
    -> SUM(avail_balance) avail_balance
    -> FROM account
    -> GROUP BY product_cd, open_branch_id WITH ROLLUP;
+------------+----------------+---------------+
| product_cd | open_branch_id | avail_balance |
+------------+----------------+---------------+
| BUS        |              2 |       9345.55 |
| BUS        |              4 |          0.00 |
| BUS        |           NULL |       9345.55 |
| CD         |              1 |      11500.00 |
| CD         |              2 |       8000.00 |
| CD         |           NULL |      19500.00 |
| CHK        |              1 |        782.16 |
| CHK        |              2 |       3315.77 |
| CHK        |              3 |       1057.75 |
| CHK        |              4 |      67852.33 |
| CHK        |           NULL |      73008.01 |
| MM         |              1 |      14832.64 |
| MM         |              3 |       2212.50 |
| MM         |           NULL |      17045.14 |
| SAV        |              1 |        767.77 |
| SAV        |              2 |        700.00 |
| SAV        |              4 |        387.99 |
| SAV        |           NULL |       1855.76 |
| SBL        |              3 |      50000.00 |
| SBL        |           NULL |      50000.00 |
| NULL       |           NULL |     170754.46 |
+------------+----------------+---------------+
21 rows in set (0.00 sec)
  | 
  
分组过滤条件
当使用分组数据时,不能使用WHERE子句,过滤子句应该使用HAVING子句。在分组之后如果需要对数据应用过滤条件,可以在HAVING子句中放置这些条件。
可以在HAVING子句中包含未在SELECT子句中出现的聚集函数。