MySQL最常用分组聚合函数

一、聚合函数(aggregation function)---也就是组函数

  在一个行的集合(一组行)上进行操作,对每个组给一个结果。

常用的组函数:


AVG([distinct] expr)


求平均值


COUNT({*|[distinct] } expr)


统计行的数量


MAX([distinct] expr)


求最大值


MIN([distinct] expr)


求最小值


SUM([distinct] expr)


求累加和

  ①每个组函数接收一个参数

  ②默认情况下,组函数忽略列值为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 TENNISmysql> show tables;
+-------------------+
| Tables_in_TENNIS  |
+-------------------+
| COMMITTEE_MEMBERS |
| MATCHES           |
| PENALTIES         |
| PLAYERS           |
| TEAMS             |
+-------------------+
5 rows in set (0.00 sec)

1、count函数

①count(*):返回表中满足where条件的行的数量

mysql> select count(*) from salary_tab where salary=‘1000‘;
+----------+
| count(*) |
+----------+
|        2 |
+----------+

mysql> select count(*) from salary_tab;  #没有条件,默认统计表数据行数
+----------+
| count(*) |
+----------+
|        5 |
+----------+

②count(列):返回列值非空的行的数量

mysql> select count(salary) from salary_tab;
+---------------+
| count(salary) |
+---------------+
|             4 |
+---------------+

③count(distinct 列):返回列值非空的、并且列值不重复的行的数量

mysql> select count(distinct salary) from salary_tab;
+------------------------+
| count(distinct salary) |
+------------------------+
|                      3 |
+------------------------+

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,0)) from salary_tab;
+-----------------------+
| avg(ifnull(salary,0)) |
+-----------------------+
|           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>=2000
    -> group by salary;
+---------+----------+
| salary  | count(*) |
+---------+----------+
| 2000.00 |        1 |
| 3000.00 |        1 |
+---------+----------+

2)指定多个分组列,‘大组中再分小组’

mysql> select userid,count(salary) from salary_tab
    -> where salary>=2000
    -> group by salary,userid;
+--------+---------------+
| userid | count(salary) |
+--------+---------------+
|      2 |             1 |
|      3 |             1 |
+--------+---------------+

3)根据表达式分组

mysql> select year(payment_date),count(*)
    -> from PENALTIES
    -> group by year(payment_date);
+--------------------+----------+
| year(payment_date) | count(*) |
+--------------------+----------+
|               1980 |        3 |
|               1981 |        1 |
|               1982 |        1 |
|               1983 |        1 |
|               1984 |        2 |
+--------------------+----------+
5 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(*) |
+--------+----------+
|      2 |        5 |
|      1 |        8 |
+--------+----------+
2 rows in set (0.00 sec)

mysql> select teamno,count(*)
    -> from MATCHES
    -> group by teamno desc;  #可以把desc(或者asc)包含到group by子句中简化
+--------+----------+
| teamno | count(*) |
+--------+----------+
|      2 |        5 |
|      1 |        8 |
+--------+----------+
2 rows in set (0.00 sec)

2、GROUP_CONCAT()函数

  函数的值等于属于一个组的指定列的所有值,以逗号隔开,并且以字符串表示。

例1:对于每个球队,得到其编号和所有球员的编号

mysql> select teamno,group_concat(playerno)
    -> from MATCHES
    -> group by teamno;
+--------+------------------------+
| teamno | group_concat(playerno) |
+--------+------------------------+
|      1 | 6,6,6,44,83,2,57,8     |
|      2 | 27,104,112,112,8       |
+--------+------------------------+
2 rows in set (0.01 sec)

如果没有group by子句,group_concat返回一列的所有值

例2:得到所有的罚款编号列表

mysql> select group_concat(paymentno)
    -> from PENALTIES;
+-------------------------+
| group_concat(paymentno) |
+-------------------------+
| 1,2,3,4,5,6,7,8         |
+-------------------------+
1 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    |        2 |
| F   | Inglewood |        1 |
| F   | Midhurst  |        1 |
| F   | Plymouth  |        1 |
| F   | NULL      |        5 |
| M   | Douglas   |        1 |
| M   | Inglewood |        1 |
| M   | Stratford |        7 |
| M   | NULL      |        9 |
| NULL | NULL      |       14 |
+-----+-----------+----------+
10 rows in set (0.00 sec)

4、HAVING子句:对分组结果进行过滤

注意:

  不能使用WHERE子句对分组后的结果进行过滤

  不能在WHERE子句中使用组函数,仅用于过滤行

mysql> select playerno
    -> from PENALTIES
    -> where count(*)>1
    -> group by playerno;
ERROR 1111 (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>=2000
    -> group by salary
    -> having count(*)>=0;
+---------+----------+
| salary  | count(*) |
+---------+----------+
| 2000.00 |        1 |
| 3000.00 |        1 |
+---------+----------+

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 1054 (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   |        2 |
| Midhurst |        1 |
+----------+----------+
2 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 |
+------+------+
|  123 | abc  |
|  321 | cba  |
+------+------+
2 rows in set (0.00 sec)

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  |
|    1 | a    |
|    2 | A    |
+------+------+
4 rows in set (0.00 sec)

如果要对合并后的整个结果集进行排序,ORDER BY子句只能出现在最后面的查询中

注意:

  在去重操作时,如果列值中包含NULL值,认为它们是相等的

时间: 2024-10-20 21:49:30

MySQL最常用分组聚合函数的相关文章

窗口聚合函数与分组聚合函数的异同

窗口聚合函数与分组聚合函数的功能是相同的:唯一不同的是,分组聚合函数通过分组查询来进行,而窗口聚合函数通过OVER子句定义的窗口来进行. --<T-SQL性能调优秘笈---基于SQL Server2012窗口函数>2.1.1窗口聚合函数描述

GROUP BY和HAVING 以及mysql中常用的日期函数

一.mysql中的GROUP BY和HAVINGGROUP BY常见的是和聚合函数(SUM,MIN,MAX,COUNT)搭配使用. 比如:SELECT category,SUM(money) AS `total` FROM user_money GROUP BY category;按类别分组统计user_money表每个类别总计有多少money 现在如果增加个条件,需要统计每个类别中支出的money总量,比如rule=1为支出,则改写语句为SELECT category,SUM(money) A

MySQL一些常用的时间函数 current_timestamp()

mysql自带的一些函数功能也是很强大的,这里整理了一下时间方面的 //获取当前时间戳 current_timestamp() yyyy-mm-dd hh:ii:ss curdate() yyyy-mm-dd curtime() hh:ii:ss //格式化时间戳的日期函数 date('yyyy-mm-dd hh:ii:ss') yyyy-mm-dd year('yyyy-mm-dd hh:ii:ss') yyyy month('yyyy-mm-dd hh:ii:ss') mm day('yyy

MYSQL学习笔记 (五)常用的聚合函数

1.COUNT(e1) 语法:COUNT(e1) 参数:e1为一个表达式,可以是任意的数据类型 返回:返回数值型数据 作用:返回e1指定列不为空的记录总数 例子: 1)单独使用 2)与group by搭配使用 2. 语法:SUM(e1) 参数:e1为类型为数值型的表达式 返回:返回数值型数据 作用:对e1指定的列进行求和计算   例子: 1)单独使用 2)与group by联合使用 3.MIN(e1).MAX(e1) 语法:MIN(e1).MAX(e1) 参数:e1为一个字符型.日期型或数值类型

mysql中 常用的时间函数

时间函数: now:当前时间带格式 mysql> select now(); +---------------------+ | now() | +---------------------+ | 2015-09-06 10:47:33 | +---------------------+ 1 row in set (0.00 sec) to_days:给定一个日期date, 返回一个天数 (从年份0开始的天数 ). mysql> select TO_DAYS(NOW()); +--------

Hibernate常用的聚合函数

package entity; //持久化类 import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; //HQl查询图书信息 @Entity @Table public class HqlQuery {

数据库常用的聚合函数

1 计算记录的总数 SELECT COUNT(ID) FROM TABLE (WHERE...)       where条件视情况加 2计算某列的和 SELECT SUM(数字字段) AS SUMCOUNT FROM TABLENAME; 3查询字段的最大最小 SELECT MAX(字段) FROM TABLENAME SELECT MIN(字段)  FROM TABLENAME 4排序 SELECT  字段1,字段2,字段3 ...  FROM TABLENAME ORDER BY 字段 原文

MongoDB学习总结(三) —— 常用聚合函数

上一篇介绍了MongoDB增删改查命令的基本用法,这一篇来学习一下MongoDB的一些基本聚合函数. 下面我们直奔主题,用简单的实例依次介绍一下. 1.count()函数 集合的count函数是最简单的聚合函数,返回集合中文档的数量. 2.distinct()函数 用于找出一个集合中,给定键的所有不同的值. 我们还可通过在数据库上运行命令,来执行distinct聚合函数,此时我们必须指定集合和键: 命令参数中,键"distinct"指定统计的集合名称,键"key"指

10-31C#基础--数据库查询语句之聚合函数、分组

在查询语句时,也存在一些方法和属性,而这些方法在查询时统称为函数,便利查询时使用 聚合函数(都是针对字段操作) 聚合是缩减一系列输入值的表达式,例如缩减为单个值. Select*from biao 1.--求平均分AVG:只能对数字类型的操作,返回一个值(返回非null值的平均值) Select AVG(age)from biao--执行后没有列名 Select AVG(age) as nianing from biao---执行后有列名,加as. --放在select...from之间的一定是