MySQL最常用分组聚合函数
一、聚合函数(aggregation function)---也就是组函数
在一个行的集合(一组行)上进行操作,对每个组给一个结果。
常用的组函数:
求平均值 |
|
统计行的数量 |
|
求最大值 |
|
求最小值 |
|
求累加和 |
①每个组函数接收一个参数
②默认情况下,组函数忽略列值为null的行,不参与计算
③有时,会使用关键字distinct剔除字段值重复的条数
注意:
1)当使用组函数的select语句中没有group by子句时,中间结果集中的所有行自动形成一组,然后计算组函数;
2)组函数不允许嵌套,例如:count(max(…));
3)组函数的参数可以是列或是函数表达式;
4)一个SELECT子句中可出现多个聚集函数。
实验演示用表:
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)
mysql> use TENNIS
mysql> show tables;
+-------------------+
| Tables_in_TENNIS |
+-------------------+
| COMMITTEE_MEMBERS |
| MATCHES |
| PENALTIES |
| PLAYERS |
| TEAMS |
+-------------------+
rows in set (0.00 sec)
1、count函数
①count(*):返回表中满足where条件的行的数量
mysql> select count(*) from salary_tab where salary='';
+----------+
| count(*) |
+----------+
| |
+----------+ mysql> select count(*) from salary_tab; #没有条件,默认统计表数据行数
+----------+
| count(*) |
+----------+
| |
+----------+
②count(列):返回列值非空的行的数量
mysql> select count(salary) from salary_tab;
+---------------+
| count(salary) |
+---------------+
| |
+---------------+
③count(distinct 列):返回列值非空的、并且列值不重复的行的数量
mysql> select count(distinct salary) from salary_tab;
+------------------------+
| count(distinct salary) |
+------------------------+
| |
+------------------------+
④count(expr):根据表达式统计数据
mysql> select * from TT;
+------+------------+
| UNIT | DATE |
+------+------------+
| a | 2018-04-03 |
| a | 2017-12-12 |
| b | 2018-01-01 |
| b | 2018-04-03 |
| c | 2016-06-06 |
| d | 2018-03-03 |
+------+------------+
6 rows in set (0.00 sec) mysql> select UNIT as '单位',
-> COUNT(TO_DAYS(DATE)=TO_DAYS(NOW()) or null) as '今日统计',
-> COUNT(YEAR(DATE)=YEAR(NOW()) or null) as '今年统计'
-> from v_jjd
-> group by JJDW;
+------+----------+----------+
| 单位 | 今日统计 | 今年统计 |
+------+----------+----------+
| a | 1 | 1 |
| b | 1 | 2 |
| c | 0 | 0 |
| d | 0 | 1 |
+------+----------+----------+
4 rows in set (0.00 sec)
2、max和min函数---统计列中的最大最小值
mysql> select max(salary) from salary_tab;
+-------------+
| max(salary) |
+-------------+
| 3000.00 |
+-------------+ mysql> select min(salary) from salary_tab;
+-------------+
| min(salary) |
+-------------+
| 1000.00 |
+-------------+
注意:如果统计的列中只有NULL值,那么MAX和MIN就返回NULL
3、sum和avg函数---求和与求平均
!!表中列值为null的行不参与计算
mysql> select sum(salary) from salary_tab;
+-------------+
| sum(salary) |
+-------------+
| 7000.00 |
+-------------+ mysql> select avg(salary) from salary_tab;
+-------------+
| avg(salary) |
+-------------+
| 1750.000000 |
+-------------+ mysql> select avg(ifnull(salary,)) from salary_tab;
+-----------------------+
| avg(ifnull(salary,)) |
+-----------------------+
| 1400.000000 |
+-----------------------+
注意:要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。
二、分组SELECT
SELECT select_expr [, select_expr ...] [FROM table_references [PARTITION partition_list] [WHERE where_condition] [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition] [ORDER BY {col_name | expr | position} [ASC | DESC], ...] [LIMIT {[offset,] row_count | row_count OFFSET offset}]
分组SELECT的基本格式:
select [聚合函数] 字段名 from 表名
[where 查询条件]
[group by 字段名]
[having 过滤条件]
1、group by子句
根据给定列或者表达式的每一个不同的值将表中的行分成不同的组,使用组函数返回每一组的统计信息
规则:
①出现在SELECT子句中的单独的列,必须出现在GROUP BY子句中作为分组列
②分组列可以不出现在SELECT子句中
③分组列可出现在SELECT子句中的一个复合表达式中
④如果GROUP BY后面是一个复合表达式,那么在SELECT子句中,它必须整体作为一个表达式的一部分才能使用。
1)指定一个列进行分组
mysql> select salary,count(*) from salary_tab
-> where salary>=
-> group by salary;
+---------+----------+
| salary | count(*) |
+---------+----------+
| 2000.00 | |
| 3000.00 | |
+---------+----------+
2)指定多个分组列,‘大组中再分小组’
mysql> select userid,count(salary) from salary_tab
-> where salary>=
-> group by salary,userid;
+--------+---------------+
| userid | count(salary) |
+--------+---------------+
| | |
| | |
+--------+---------------+
3)根据表达式分组
mysql> select year(payment_date),count(*)
-> from PENALTIES
-> group by year(payment_date);
+--------------------+----------+
| year(payment_date) | count(*) |
+--------------------+----------+
| | |
| | |
| | |
| | |
| | |
+--------------------+----------+
rows in set (0.00 sec)
4)带有排序的分组:如果分组列和排序列相同,则可以合并group by和order by子句
mysql> select teamno,count(*)
-> from MATCHES
-> group by teamno
-> order by teamno desc;
+--------+----------+
| teamno | count(*) |
+--------+----------+
| | |
| | |
+--------+----------+
rows in set (0.00 sec) mysql> select teamno,count(*)
-> from MATCHES
-> group by teamno desc; #可以把desc(或者asc)包含到group by子句中简化
+--------+----------+
| teamno | count(*) |
+--------+----------+
| | |
| | |
+--------+----------+
rows in set (0.00 sec)
对于分组聚合注意:
通过select在返回集字段中,这些字段要么就要包含在group by语句后面,作为分组的依据,要么就要被包含在聚合函数中。我们可以将group by操作想象成如下的一个过程:首先系统根据select语句得到一个结果集,然后根据分组字段,将具有相同分组字段的记录归并成了一条记录。这个时候剩下的那些不存在与group by语句后面作为分组依据的字段就很有可能出现多个值,但是目前一种分组情况只有一条记录,一个数据格是无法放入多个数值的,所以这个时候就需要通过一定的处理将这些多值的列转化成单值,然后将其放在对应的数据格中,那么完成这个步骤的就是前面讲到的聚合函数,这也就是为什么这些函数叫聚合函数了。
2、GROUP_CONCAT()函数
函数的值等于属于一个组的指定列的所有值,以逗号隔开,并且以字符串表示。
例1:对于每个球队,得到其编号和所有球员的编号
mysql> select teamno,group_concat(playerno)
-> from MATCHES
-> group by teamno;
+--------+------------------------+
| teamno | group_concat(playerno) |
+--------+------------------------+
| | ,,,,,,, |
| | ,,,, |
+--------+------------------------+
rows in set (0.01 sec)
如果没有group by子句,group_concat返回一列的所有值
例2:得到所有的罚款编号列表
mysql> select group_concat(paymentno)
-> from PENALTIES;
+-------------------------+
| group_concat(paymentno) |
+-------------------------+
| ,,,,,,, |
+-------------------------+
row in set (0.00 sec)
3、with rollup子句:用来要求在一条group by子句中进行多个不同的分组
用的比较少点,但是有时可以根据具体的需求使用
如果有子句GROUP BY E1,E2,E3,E4 WITH ROLLUP
那么将分别执行以下分组:[E1,E2,E3,E4]、[E1,E2,E3]、[E1,E2]、[E1]、[]
注意:[ ]表示所有行都分在一组中
示例:按照球员的性别和居住城市,统计球员的总数;统计每个性别球员的总数;统计所有球员的总数
mysql> select sex,town,count(*)
-> from PLAYERS
-> group by sex,town with rollup;
+-----+-----------+----------+
| sex | town | count(*) |
+-----+-----------+----------+
| F | Eltham | |
| F | Inglewood | |
| F | Midhurst | |
| F | Plymouth | |
| F | NULL | |
| M | Douglas | |
| M | Inglewood | |
| M | Stratford | |
| M | NULL | |
| NULL | NULL | |
+-----+-----------+----------+
rows in set (0.00 sec)
4、HAVING子句:对分组结果进行过滤
注意:
不能使用WHERE子句对分组后的结果进行过滤
不能在WHERE子句中使用组函数,仅用于过滤行
mysql> select playerno
-> from PENALTIES
-> where count(*)>
-> group by playerno;
ERROR (HY000): Invalid use of group function
因为WHERE子句比GROUP BY先执行,而组函数必须在分完组之后才执行,且分完组后必须使用having子句进行结果集的过滤。
基本语法:
SELECT select_expr [, select_expr ...] FROM table_name [WHERE where_condition] [GROUP BY {col_name | expr} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition]
!!!having子语句与where子语句区别:
where子句在分组前对记录进行过滤;
having子句在分组后对记录进行过滤
mysql> select salary,count(*) from salary_tab
-> where salary>=
-> group by salary
-> having count(*)>=;
+---------+----------+
| salary | count(*) |
+---------+----------+
| 2000.00 | |
| 3000.00 | |
+---------+----------+
1)HAVING可以单独使用而不和GROUP BY配合,如果只有HAVING子句而没有GROUP BY,表中所有的行分为一组
2)HAVING子句中可以使用组函数
3)HAVING子句中的列,要么出现在一个组函数中,要么出现在GROUP BY子句中(否则出错)
mysql> select town,count(*)
-> from PLAYERS
-> group by town
-> having birth_date>'1970-01-01';
ERROR (42S22): Unknown column 'birth_date' in 'having clause'
mysql> select town,count(*)
-> from PLAYERS
-> group by town
-> having town in ('Eltham','Midhurst');
+----------+----------+
| town | count(*) |
+----------+----------+
| Eltham | |
| Midhurst | |
+----------+----------+
rows in set (0.00 sec)
三、集合查询操作
union用于把两个或者多个select查询的结果集合并成一个
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
默认情况下,UNION = UNION DISTINCT
①进行合并的两个查询,其SELECT列表必须在数量和对应列的数据类型上保持一致;
②默认会去掉两个查询结果集中的重复行;默认结果集不排序;
③最终结果集的列名来自于第一个查询的SELECT列表
UNION ALL不去掉结果集中重复的行
注:联合查询结果使用第一个select语句中的字段名
mysql> select * from t1;
+------+------+
| num | addr |
+------+------+
| | abc |
| | cba |
+------+------+
rows in set (0.00 sec) mysql> select * from t2;
+------+------+
| id | name |
+------+------+
| | a |
| | A |
+------+------+
rows in set (0.00 sec) mysql> select * from t1
-> union
-> select * from t2;
+------+------+
| num | addr |
+------+------+
| | abc |
| | cba |
| | a |
| | A |
+------+------+
rows in set (0.00 sec)
如果要对合并后的整个结果集进行排序,ORDER BY子句只能出现在最后面的查询中
注意:
在去重操作时,如果列值中包含NULL值,认为它们是相等的
MySQL最常用分组聚合函数的更多相关文章
- mysql数据库查询和聚合函数
1.模糊查询 like % 表示多个任意字符 _ 表示任意一个字符 例如:查询黄姓同学 select * from student where name '黄%' select * from stud ...
- MySQL 常用的聚合函数
[常用的聚合函数] mysql聚合函数一般用户统计一列值进行计算,然后返回计算结果.一般于分组group by 配合使用. count //统计个数 select count(*) from test ...
- GROUP BY和HAVING 以及mysql中常用的日期函数
一.mysql中的GROUP BY和HAVINGGROUP BY常见的是和聚合函数(SUM,MIN,MAX,COUNT)搭配使用. 比如:SELECT category,SUM(money) AS ` ...
- 深入学习之mysql(四)聚合函数
聚合函数:COUNT统计记录的条数.SUM求和函数.AVG求平均值.MAX求最大值.MIN求最小值 一.COUNT练习: 1.统计学校一共有多少个学生: mysql> SELECT COUN ...
- ORACLE字符串分组聚合函数(字符串连接聚合函数)
ORACLE字符串连接分组串聚函数 wmsys.wm_concat SQL代码: select grp, wmsys.wm_concat(str) grp, 'a1' str from dual un ...
- MySql 学习之路-聚合函数
下面是mysql 数据库中经常用到的聚合函数的简单实例 -- 创建学生表 create table student ( id int primary key auto_increment commen ...
- mysql——单表查询——聚合函数——概念
使用聚合函数查询 group by关键字通常和聚合函数一起使用 .count()函数 count()函数用来统计记录的条数 举例:使用count()函数统计employee表的记录数 select c ...
- Flask聚合函数(基本聚合函数、分组聚合函数、去重聚合函数))
Flask聚合函数 1.基本聚合函数(sun/count/max/min/avg) 使用聚合函数先导入:from sqlalchemy import func 使用方法: sun():func.sum ...
- mysql常用的聚合函数
GROUP BY(聚合)函数本章论述了用于一组数值操作的 group (集合)函数.除非另作说明, group 函数会忽略 NULL 值. 假如你在一个不包含 ROUP BY子句的语句中使用一个 gr ...
随机推荐
- Codeblocks快捷键
Codeblocks快捷键: Ctrl+Shift+Enter:复制控制台exe内容 Ctrl+Z:撤销 Ctrl+F:查找 Ctrl+R:查找替换功能 Ctrl+Shift+C:加注释 C ...
- 百度地图JavascriptApi Marker平滑移动及车头指向行径方向
相信只要是使用百度地图做实时定位服务的朋友都会遇到这个问题,在对坐标位置进行覆盖物展示的时候,会出现由于获取坐标数据时间或者两个坐标点相距过远,导致在视觉上看Marker移动就像"僵尸跳&q ...
- Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳
前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...
- 1684: [Usaco2005 Oct]Close Encounter
1684: [Usaco2005 Oct]Close Encounter Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 387 Solved: 181[ ...
- SharePoint 切换用户的小技巧
前言 从SharePoint 2013开始,SharePoint就已经去掉了”Sign in as Different User”这个功能,也就是无法切换用户登录.当然,后来我们通过修改CONTROL ...
- Rsync的工作方式
Rsync的工作方式(来自网络) 1)拷贝本地文件: 当SRC和DES路径信息中不包含冒号":"分隔符时,就启用这种工作模式: [root@cmmailapp1 /]# rsync ...
- 消息映射(C++)(转)
摘要:控件通知消息有很多种,但是有一种是很常用,但是又不是很容易掌握的,那就是WM_NOTIFY,我试着对此做一下比较全面的论述,有不对的地方,还希望各路大虾批评指正. 控件通知消息 ...
- 【JavaWeb】Session(转)
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自 ...
- Android实战(一)学习了多个控件实现登录及记住密码功能
首先确定一下需要的控件: 两个EditText:用于输入账号和密码 一个button:用于登录查看账号和密码是否正确 一个checkbox:用于记住密码和账户 一个Androidstudio:用于编写 ...
- webpack快速掌握教程
转载http://yijiebuyi.com/blog/46fb97b11fb8f4055e0b04d1cecb1f69.html #为什么用webpack 如果我们 前端 javascript 能像 ...