一、聚合函数(aggregation function)—也就是组函数
在一个行的集合(一组行)上进行操作,对每个组给一个结果。
常用的组函数:
| 
 求平均值  | 
|
| 
 统计行的数量  | 
|
| 
 求最大值  | 
|
| 
 求最小值  | 
|
| 
 求累加和  | 
①每个组函数接收一个参数
②默认情况下,组函数忽略列值为null的行,不参与计算
③有时,会使用关键字distinct剔除字段值重复的条数
注意:
1)当使用组函数的select语句中没有group by子句时,中间结果集中的所有行自动形成一组,然后计算组函数;
2)组函数不允许嵌套,例如:count(max(…));
3)组函数的参数可以是列或是函数表达式;
4)一个SELECT子句中可出现多个聚集函数。
实验演示用表:
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						<span style="font-size: 16px;">mysql> select * from salary_tab; +--------+---------+ | userid | salary  | +--------+---------+ |      1 | 1000.00 | |      2 | 2000.00 | |      3 | 3000.00 | |      4 |    NULL | |      5 | 1000.00 | +--------+---------+ 5 rows in set (0.00 sec)</span><span style="font-size: 16px;"> </span>  | 
					
| 
					 1 2 3 4 5 6 7 8 9 10 11 12  | 
						<span style="font-size: 16px;">mysql> use TENNIS</span> <span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> show tables; </span>+-------------------+ | Tables_in_TENNIS  | +-------------------+ | COMMITTEE_MEMBERS | | MATCHES           | | PENALTIES         | | PLAYERS           | | TEAMS             | +-------------------+ <span style="color: rgba(128, 0, 128, 1);">5</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
①count(*):返回表中满足where条件的行的数量
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> count(*) <span style="color: rgba(0, 0, 255, 1);">from</span> salary_tab <span style="color: rgba(0, 0, 255, 1);">where</span> salary=<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">1000</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; </span>+----------+ | count(*) | +----------+ |        <span style="color: rgba(128, 0, 128, 1);">2</span> | +----------+<span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> count(*) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab;  <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">#没有条件,默认统计表数据行数 </span></span>+----------+ | count(*) | +----------+ |        <span style="color: rgba(128, 0, 128, 1);">5</span> | +----------+</span>  | 
					
②count(列):返回列值非空的行的数量
| 
					 1 2 3 4 5 6  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> count(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+---------------+ | count(salary) | +---------------+ |             <span style="color: rgba(128, 0, 128, 1);">4</span> | +---------------+</span>  | 
					
③count(distinct 列):返回列值非空的、并且列值不重复的行的数量
| 
					 1 2 3 4 5 6  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> count(distinct salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+------------------------+ | count(distinct salary) | +------------------------+ |                      <span style="color: rgba(128, 0, 128, 1);">3</span> | +------------------------+</span>  | 
					
④count(expr):根据表达式统计数据
| 
					 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  | 
						<span style="font-size: 16px;">mysql<span style="color: rgba(128, 128, 128, 1);">></span> <span style="color: rgba(0, 0, 255, 1);">select</span> <span style="color: rgba(128, 128, 128, 1);">*</span> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> TT; </span><span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+------------+</span> <span style="color: rgba(128, 128, 128, 1);">|</span> UNIT <span style="color: rgba(128, 128, 128, 1);">|</span> DATE       <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+------------+</span> <span style="color: rgba(128, 128, 128, 1);">|</span> a    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2018</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">04</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">03</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> a    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2017</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">12</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">12</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> b    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2018</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">01</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">01</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> b    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2018</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">04</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">03</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> c    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2016</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">06</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">06</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> d    <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2018</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">03</span><span style="color: rgba(128, 128, 128, 1);">-</span><span style="color: rgba(128, 0, 0, 1); font-weight: bold;">03</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+------------+</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">6</span> rows <span style="color: rgba(128, 128, 128, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 0, 1); font-weight: bold;">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span><span style="color: rgba(128, 128, 128, 1);">></span> <span style="color: rgba(0, 0, 255, 1);">select</span> UNIT <span style="color: rgba(0, 0, 255, 1);">as</span> <span style="color: rgba(255, 0, 0, 1);">'</span><span style="color: rgba(255, 0, 0, 1);">单位</span><span style="color: rgba(255, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">,     </span><span style="color: rgba(128, 128, 128, 1);">-></span>     <span style="color: rgba(255, 0, 255, 1);">COUNT</span>(TO_DAYS(DATE)<span style="color: rgba(128, 128, 128, 1);">=</span>TO_DAYS(NOW()) <span style="color: rgba(128, 128, 128, 1);">or</span> <span style="color: rgba(0, 0, 255, 1);">null</span>) <span style="color: rgba(0, 0, 255, 1);">as</span> <span style="color: rgba(255, 0, 0, 1);">'</span><span style="color: rgba(255, 0, 0, 1);">今日统计</span><span style="color: rgba(255, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">,     </span><span style="color: rgba(128, 128, 128, 1);">-></span>     <span style="color: rgba(255, 0, 255, 1);">COUNT</span>(<span style="color: rgba(255, 0, 255, 1);">YEAR</span>(DATE)<span style="color: rgba(128, 128, 128, 1);">=</span><span style="color: rgba(255, 0, 255, 1);">YEAR</span>(NOW()) <span style="color: rgba(128, 128, 128, 1);">or</span> <span style="color: rgba(0, 0, 255, 1);">null</span>) <span style="color: rgba(0, 0, 255, 1);">as</span> <span style="color: rgba(255, 0, 0, 1);">'</span><span style="color: rgba(255, 0, 0, 1);">今年统计</span><span style="color: rgba(255, 0, 0, 1);">'</span>     <span style="color: rgba(128, 128, 128, 1);">-></span> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> v_jjd     </span><span style="color: rgba(128, 128, 128, 1);">-></span> <span style="color: rgba(0, 0, 255, 1);">group</span> <span style="color: rgba(0, 0, 255, 1);">by</span><span style="color: rgba(0, 0, 0, 1);"> JJDW; </span><span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+----------+----------+</span> <span style="color: rgba(128, 128, 128, 1);">|</span> 单位  <span style="color: rgba(128, 128, 128, 1);">|</span> 今日统计  <span style="color: rgba(128, 128, 128, 1);">|</span> 今年统计  <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+----------+----------+</span> <span style="color: rgba(128, 128, 128, 1);">|</span> a    <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">1</span> <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">1</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> b    <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">1</span> <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">2</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> c    <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">0</span> <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">0</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">|</span> d    <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">0</span> <span style="color: rgba(128, 128, 128, 1);">|</span>        <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">1</span> <span style="color: rgba(128, 128, 128, 1);">|</span> <span style="color: rgba(128, 128, 128, 1);">+</span><span style="color: rgba(0, 128, 128, 1);">--</span><span style="color: rgba(0, 128, 128, 1);">----+----------+----------+</span> <span style="color: rgba(128, 0, 0, 1); font-weight: bold;">4</span> rows <span style="color: rgba(128, 128, 128, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 0, 1); font-weight: bold;">0.00</span> sec)</span>  | 
					
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> max(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+-------------+ | max(salary) | +-------------+ |     <span style="color: rgba(128, 0, 128, 1);">3000.00</span> | +-------------+<span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> min(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+-------------+ | min(salary) | +-------------+ |     <span style="color: rgba(128, 0, 128, 1);">1000.00</span> | +-------------+</span>  | 
					
注意:如果统计的列中只有NULL值,那么MAX和MIN就返回NULL
!!表中列值为null的行不参与计算
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> sum(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+-------------+ | sum(salary) | +-------------+ |     <span style="color: rgba(128, 0, 128, 1);">7000.00</span> | +-------------+<span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> avg(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+-------------+ | avg(salary) | +-------------+ | <span style="color: rgba(128, 0, 128, 1);">1750.000000</span> | +-------------+<span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> avg(ifnull(salary,<span style="color: rgba(128, 0, 128, 1);">0</span>)) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab; </span>+-----------------------+ | avg(ifnull(salary,<span style="color: rgba(128, 0, 128, 1);">0</span>)) | +-----------------------+ |           <span style="color: rgba(128, 0, 128, 1);">1400.000000</span> | +-----------------------+</span>  | 
					
注意:要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。
二、分组SELECT
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | 
						<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">SELECT select_expr [, select_expr ...]     [FROM table_references       [PARTITION partition_list]     [WHERE where_condition]     [GROUP BY {col_name </span>| expr |<span style="color: rgba(0, 0, 0, 1);"> position}       [ASC </span>|<span style="color: rgba(0, 0, 0, 1);"> DESC], ... [WITH ROLLUP]]     [HAVING where_condition]     [ORDER BY {col_name </span>| expr |<span style="color: rgba(0, 0, 0, 1);"> position}       [ASC </span>|<span style="color: rgba(0, 0, 0, 1);"> DESC], ...] [LIMIT {[offset,] row_count </span>| row_count OFFSET offset}]</span>  | 
					
分组SELECT的基本格式:
select [聚合函数] 字段名 from 表名
[where 查询条件]
[group by 字段名]
[having 过滤条件]
1、group by子句
根据给定列或者表达式的每一个不同的值将表中的行分成不同的组,使用组函数返回每一组的统计信息
规则:
①出现在SELECT子句中的单独的列,必须出现在GROUP BY子句中作为分组列
②分组列可以不出现在SELECT子句中
③分组列可出现在SELECT子句中的一个复合表达式中
④如果GROUP BY后面是一个复合表达式,那么在SELECT子句中,它必须整体作为一个表达式的一部分才能使用。
1)指定一个列进行分组
| 
					 1 2 3 4 5 6 7 8 9  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> salary,count(*) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab     </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> salary>=<span style="color: rgba(128, 0, 128, 1);">2000</span>     -><span style="color: rgba(0, 0, 0, 1);"> group by salary;    </span>+---------+----------+ | salary  | count(*) | +---------+----------+ | <span style="color: rgba(128, 0, 128, 1);">2000.00</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | <span style="color: rgba(128, 0, 128, 1);">3000.00</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | +---------+----------+</span>  | 
					
2)指定多个分组列,‘大组中再分小组’
| 
					 1 2 3 4 5 6 7 8 9  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> userid,count(salary) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab     </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> salary>=<span style="color: rgba(128, 0, 128, 1);">2000</span>     -><span style="color: rgba(0, 0, 0, 1);"> group by salary,userid;    </span>+--------+---------------+ | userid | count(salary) | +--------+---------------+ |      <span style="color: rgba(128, 0, 128, 1);">2</span> |             <span style="color: rgba(128, 0, 128, 1);">1</span> | |      <span style="color: rgba(128, 0, 128, 1);">3</span> |             <span style="color: rgba(128, 0, 128, 1);">1</span> | +--------+---------------+</span>  | 
					
3)根据表达式分组
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> year(payment_date),count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PENALTIES     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by year(payment_date); </span>+--------------------+----------+ | year(payment_date) | count(*) | +--------------------+----------+ |               <span style="color: rgba(128, 0, 128, 1);">1980</span> |        <span style="color: rgba(128, 0, 128, 1);">3</span> | |               <span style="color: rgba(128, 0, 128, 1);">1981</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | |               <span style="color: rgba(128, 0, 128, 1);">1982</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | |               <span style="color: rgba(128, 0, 128, 1);">1983</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | |               <span style="color: rgba(128, 0, 128, 1);">1984</span> |        <span style="color: rgba(128, 0, 128, 1);">2</span> | +--------------------+----------+ <span style="color: rgba(128, 0, 128, 1);">5</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
4)带有排序的分组:如果分组列和排序列相同,则可以合并group by和order by子句
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> teamno,count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> MATCHES     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by teamno     </span>-><span style="color: rgba(0, 0, 0, 1);"> order by teamno desc; </span>+--------+----------+ | teamno | count(*) | +--------+----------+ |      <span style="color: rgba(128, 0, 128, 1);">2</span> |        <span style="color: rgba(128, 0, 128, 1);">5</span> | |      <span style="color: rgba(128, 0, 128, 1);">1</span> |        <span style="color: rgba(128, 0, 128, 1);">8</span> | +--------+----------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> teamno,count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> MATCHES     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by teamno desc;  <span style="font-family: 'Microsoft YaHei'; color: rgba(255, 0, 0, 1);">#可以把desc(或者asc)包含到group by子句中简化 </span></span>+--------+----------+ | teamno | count(*) | +--------+----------+ |      <span style="color: rgba(128, 0, 128, 1);">2</span> |        <span style="color: rgba(128, 0, 128, 1);">5</span> | |      <span style="color: rgba(128, 0, 128, 1);">1</span> |        <span style="color: rgba(128, 0, 128, 1);">8</span> | +--------+----------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
对于分组聚合注意:
通过select在返回集字段中,这些字段要么就要包含在group by语句后面,作为分组的依据,要么就要被包含在聚合函数中。我们可以将group by操作想象成如下的一个过程:首先系统根据select语句得到一个结果集,然后根据分组字段,将具有相同分组字段的记录归并成了一条记录。这个时候剩下的那些不存在与group by语句后面作为分组依据的字段就很有可能出现多个值,但是目前一种分组情况只有一条记录,一个数据格是无法放入多个数值的,所以这个时候就需要通过一定的处理将这些多值的列转化成单值,然后将其放在对应的数据格中,那么完成这个步骤的就是前面讲到的聚合函数,这也就是为什么这些函数叫聚合函数了。
2、GROUP_CONCAT()函数
函数的值等于属于一个组的指定列的所有值,以逗号隔开,并且以字符串表示。
例1:对于每个球队,得到其编号和所有球员的编号
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span><span style="color: rgba(0, 0, 0, 1);"> teamno,group_concat(playerno)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> MATCHES     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by teamno; </span>+--------+------------------------+ | teamno | group_concat(playerno) | +--------+------------------------+ |      <span style="color: rgba(128, 0, 128, 1);">1</span> | <span style="color: rgba(128, 0, 128, 1);">6</span>,<span style="color: rgba(128, 0, 128, 1);">6</span>,<span style="color: rgba(128, 0, 128, 1);">6</span>,<span style="color: rgba(128, 0, 128, 1);">44</span>,<span style="color: rgba(128, 0, 128, 1);">83</span>,<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 128, 1);">57</span>,<span style="color: rgba(128, 0, 128, 1);">8</span>     | |      <span style="color: rgba(128, 0, 128, 1);">2</span> | <span style="color: rgba(128, 0, 128, 1);">27</span>,<span style="color: rgba(128, 0, 128, 1);">104</span>,<span style="color: rgba(128, 0, 128, 1);">112</span>,<span style="color: rgba(128, 0, 128, 1);">112</span>,<span style="color: rgba(128, 0, 128, 1);">8</span>       | +--------+------------------------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.01</span> sec)</span>  | 
					
如果没有group by子句,group_concat返回一列的所有值
例2:得到所有的罚款编号列表
| 
					 1 2 3 4 5 6 7 8  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span><span style="color: rgba(0, 0, 0, 1);"> group_concat(paymentno)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PENALTIES; </span>+-------------------------+ | group_concat(paymentno) | +-------------------------+ | <span style="color: rgba(128, 0, 128, 1);">1</span>,<span style="color: rgba(128, 0, 128, 1);">2</span>,<span style="color: rgba(128, 0, 128, 1);">3</span>,<span style="color: rgba(128, 0, 128, 1);">4</span>,<span style="color: rgba(128, 0, 128, 1);">5</span>,<span style="color: rgba(128, 0, 128, 1);">6</span>,<span style="color: rgba(128, 0, 128, 1);">7</span>,<span style="color: rgba(128, 0, 128, 1);">8</span>         | +-------------------------+ <span style="color: rgba(128, 0, 128, 1);">1</span> row <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
3、with rollup子句:用来要求在一条group by子句中进行多个不同的分组
用的比较少点,但是有时可以根据具体的需求使用
如果有子句GROUP BY E1,E2,E3,E4 WITH ROLLUP
那么将分别执行以下分组:[E1,E2,E3,E4]、[E1,E2,E3]、[E1,E2]、[E1]、[]
注意:[ ]表示所有行都分在一组中
示例:按照球员的性别和居住城市,统计球员的总数;统计每个性别球员的总数;统计所有球员的总数
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> sex,town,count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PLAYERS     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by sex,town with rollup; </span>+-----+-----------+----------+ | sex | town      | count(*) | +-----+-----------+----------+ | F   | Eltham    |        <span style="color: rgba(128, 0, 128, 1);">2</span> | | F   | Inglewood |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | F   | Midhurst  |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | F   | Plymouth  |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | F   | NULL      |        <span style="color: rgba(128, 0, 128, 1);">5</span> | | M   | Douglas   |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | M   | Inglewood |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | M   | Stratford |        <span style="color: rgba(128, 0, 128, 1);">7</span> | | M   | NULL      |        <span style="color: rgba(128, 0, 128, 1);">9</span> | | NULL | NULL      |       <span style="color: rgba(128, 0, 128, 1);">14</span> | +-----+-----------+----------+ <span style="color: rgba(128, 0, 128, 1);">10</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
4、HAVING子句:对分组结果进行过滤
注意:
不能使用WHERE子句对分组后的结果进行过滤
不能在WHERE子句中使用组函数,仅用于过滤行
| 
					 1 2 3 4 5  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span><span style="color: rgba(0, 0, 0, 1);"> playerno     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PENALTIES     </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> count(*)><span style="color: rgba(128, 0, 128, 1);">1</span>     -><span style="color: rgba(0, 0, 0, 1);"> group by playerno; ERROR </span><span style="color: rgba(128, 0, 128, 1);">1111</span> (HY000): Invalid use of group function</span>  | 
					
因为WHERE子句比GROUP BY先执行,而组函数必须在分完组之后才执行,且分完组后必须使用having子句进行结果集的过滤。
基本语法:
| 
					 1 2 3 4 5 6 7 8 9  | 
						<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">SELECT   select_expr [, select_expr ...]    FROM  table_name    [WHERE where_condition]    [GROUP BY {col_name </span>| expr} [ASC |<span style="color: rgba(0, 0, 0, 1);"> DESC], ... [WITH ROLLUP]] [HAVING where_condition]</span></span>  | 
					
!!!having子语句与where子语句区别:
where子句在分组前对记录进行过滤;
having子句在分组后对记录进行过滤
| 
					 1 2 3 4 5 6 7 8 9 10  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> salary,count(*) <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> salary_tab     </span>-> <span style="color: rgba(0, 0, 255, 1);">where</span> salary>=<span style="color: rgba(128, 0, 128, 1);">2000</span>     -><span style="color: rgba(0, 0, 0, 1);"> group by salary     </span>-> having count(*)>=<span style="color: rgba(128, 0, 128, 1);">0</span><span style="color: rgba(0, 0, 0, 1);">; </span>+---------+----------+ | salary  | count(*) | +---------+----------+ | <span style="color: rgba(128, 0, 128, 1);">2000.00</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | | <span style="color: rgba(128, 0, 128, 1);">3000.00</span> |        <span style="color: rgba(128, 0, 128, 1);">1</span> | +---------+----------+</span>  | 
					
1)HAVING可以单独使用而不和GROUP BY配合,如果只有HAVING子句而没有GROUP BY,表中所有的行分为一组
2)HAVING子句中可以使用组函数
3)HAVING子句中的列,要么出现在一个组函数中,要么出现在GROUP BY子句中(否则出错)
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> town,count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PLAYERS     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by town     </span>-> having birth_date><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">1970-01-01</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; ERROR </span><span style="color: rgba(128, 0, 128, 1);">1054</span> (42S22): Unknown column <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">birth_date</span><span style="color: rgba(128, 0, 0, 1);">'</span> <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">having clause</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);"> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> town,count(*<span style="color: rgba(0, 0, 0, 1);">)     </span>-> <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> PLAYERS     </span>-><span style="color: rgba(0, 0, 0, 1);"> group by town     </span>-> having town <span style="color: rgba(0, 0, 255, 1);">in</span> (<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">Eltham</span><span style="color: rgba(128, 0, 0, 1);">'</span>,<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">Midhurst</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">); </span>+----------+----------+ | town     | count(*) | +----------+----------+ | Eltham   |        <span style="color: rgba(128, 0, 128, 1);">2</span> | | Midhurst |        <span style="color: rgba(128, 0, 128, 1);">1</span> | +----------+----------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span> sec)</span>  | 
					
三、集合查询操作
union用于把两个或者多个select查询的结果集合并成一个
| 
					 1 2 3 4 5 6 7 8 9  | 
						<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">SELECT ... UNION [ALL </span>|<span style="color: rgba(0, 0, 0, 1);"> DISTINCT] SELECT ... [UNION [ALL </span>|<span style="color: rgba(0, 0, 0, 1);"> DISTINCT] SELECT ...]</span></span>  | 
					
默认情况下,UNION = UNION DISTINCT
①进行合并的两个查询,其SELECT列表必须在数量和对应列的数据类型上保持一致;
②默认会去掉两个查询结果集中的重复行;默认结果集不排序;
③最终结果集的列名来自于第一个查询的SELECT列表
UNION ALL不去掉结果集中重复的行
注:联合查询结果使用第一个select语句中的字段名
| 
					 1 2 3 4 5 6 7 8  | 
						<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> t1; </span>+------+------+ | num  | addr | +------+------+ |  <span style="color: rgba(128, 0, 128, 1);">123</span> | abc  | |  <span style="color: rgba(128, 0, 128, 1);">321</span> | cba  | +------+------+ <span style="color: rgba(128, 0, 128, 1);">2</span> rows <span style="color: rgba(0, 0, 255, 1);">in</span> <span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.00</span><span style="color: rgba(0, 0, 0, 1);"> sec)</span></span>  | 
					
mysql> select * from t2;
+——+——+
| id | name |
+——+——+
| 1 | a |
| 2 | A |
+——+——+
2 rows in set (0.00 sec)
mysql> select * from t1
-> union
-> select * from t2;
+——+——+
| num | addr |
+——+——+
| 123 | abc |
| 321 | cba |
|