语法:
select 列,列 ··· from 表 group by 列(分组对象) having 条件表达式;
having 相当于where但不能用where代替
区别; where后面不能使用聚集函数
having 后面能使用聚集函数
当分组后想用聚集函数来充当查询条件时用having就行了。
1.集函数:当不与group by 连用时
AVG() 返回某列的平均值
COUNT() 返回某列的个数
MAX() 返回某列中元素的最大值
MIN() 返回某列的最小值
SUM() 返回某列的和
注意:1,这些函数不能直接嵌套:max(count(列))
2.集函数:当与group by 连用时
AVG() 返回某列中的平均值
COUNT() 返回某列的个数
MAX() 返回某列中元素的最大值
MIN() 返回某列的最小值
SUM() 返回某列的和
注意:1,这些函数不能直接嵌套:max(count(列))
2.分组的意义:
对group by 后面的列 进行合并,分组成新的表,并显示select 后面的列,但列中的值可能为多值但值只能是唯一,所以用到集函数进行,变值为唯一,这样才能显示出来。
3.分组的意义的解释
原表
mysql> select sno,cno from sc;
±------±----+
| sno | cno |
±------±----+
| 08001 | 002 |
| 08001 | 003 |
| 08001 | 004 |
| 08001 | 006 |
| 08002 | 002 |
| 08002 | 003 |
| 08003 | 001 |
| 08003 | 002 |
| 08003 | 003 |
| 08004 | 001 |
| 08005 | 007 |
| 08005 | 002 |
| 08006 | 003 |
| 08008 | 001 |
| 08008 | 003 |
| 08009 | 001 |
| 08009 | 004 |
| 08010 | 005 |
±------±----+
这时对cno进行分组,mysql> select sno,cno from sc group by cno;
然后就相当与产生了新的表(假设):
±------±----+
| sno | cno |
±------±----+
| 08003 | |
| 08004 | 001 |
| 08008 | |
| 08009 | |
| 08001 | |
| 08005 | 002 |
| 08002 | |
| 08003 | |
等
等
所以相当于sno有多个值,但sql中值只能唯一,所以这句话报错:
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'school.sc.Sno' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
但,若使用集函数,对sno多个值进行选择或相加使值唯一,这样就可以显示出来了:
mysql> select min(sno),cno from sc group by cno;
±---------±----+
| min(sno) | cno |
±---------±----+
| 08003 | 001 |
| 08001 | 002 |
| 08001 | 003 |
| 08001 | 004 |
| 08010 | 005 |
| 08001 | 006 |
| 08005 | 007 |
±---------±----+
而count(sno)这句话就证明了分组后产生了新表这一假设,但由于值为一、所以无法显示。
mysql> select count(sno),cno from sc group by cno;
±-----------±----+
| count(sno) | cno |
±-----------±----+
| 4 | 001 |
| 4 | 002 |
| 5 | 003 |
| 2 | 004 |
| 1 | 005 |
| 1 | 006 |
| 1 | 007 |
±-----------±----