Documentation Home
MySQL 8.0 参考手册  / 第 12 章函数和运算符  / 12.20聚合函数  /  12.19.1 聚合函数说明

12.19.1 聚合函数说明

本节介绍对值集进行操作的聚合函数。它们通常与GROUP BY子句一起使用以将值分组到子集中。

表 12.23 聚合函数

姓名 描述
AVG() 返回参数的平均值
BIT_AND() 返回按位与
BIT_OR() 返回按位或
BIT_XOR() 返回按位异或
COUNT() 返回返回行数的计数
COUNT(DISTINCT) 返回多个不同值的计数
GROUP_CONCAT() 返回一个连接的字符串
MAX() 返回最大值
MIN() 返回最小值
STD() 返回总体标准差
STDDEV() 返回总体标准差
STDDEV_POP() 返回总体标准差
STDDEV_SAMP() 返回样本标准差
SUM() 返回总和
VAR_POP() 返回总体标准方差
VAR_SAMP() 返回样本方差
VARIANCE() 返回总体标准方差

除非另有说明,聚合函数忽略 NULL值。

如果在不包含 GROUP BY子句的语句中使用聚合函数,则相当于对所有行进行分组。有关详细信息,请参阅 第 12.19.3 节,“MySQL 对 GROUP BY 的处理”

对于数字参数,方差和标准差函数返回一个DOUBLE值。和函数 为精确值参数(整数或)返回一个值SUM(), 为近似值参数(或 )返回一个值。 AVG()DECIMALDECIMALDOUBLEFLOATDOUBLE

和聚合函数SUM()不适 AVG()用于时间值。(他们将值转换为数字,在第一个非数字字符之后丢失所有内容。)要解决此问题,请转换为数字单位,执行聚合操作,然后转换回时间值。例子:

SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROM tbl_name;
SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROM tbl_name;

如有必要SUM()AVG()期望数字参数的函数将参数转换为数字。对于 SETor ENUM值,转换操作会导致使用基础数值。

BIT_AND()和 聚合函数执行位运算BIT_OR()BIT_XOR()它们需要 BIGINT(64 位整数)参数和返回BIGINT值。其他类型的参数被转换为 BIGINT并且可能会发生截断。

  • AVG([DISTINCT] expr)

    返回 的平均值 expr。该 DISTINCT选项可用于返回 的不同值的平均值 expr

    如果没有匹配的行,则 AVG()返回 NULL

    mysql> SELECT student_name, AVG(test_score)
           FROM student
           GROUP BY student_name;
  • BIT_AND(expr)

    返回AND中所有位 的按位expr。计算以 64 位 ( BIGINT) 精度执行。

    如果没有匹配的行,则 BIT_AND()返回一个中性值(所有位都设置为 1)。

  • BIT_OR(expr)

    返回OR中所有位 的按位expr。计算以 64 位 ( BIGINT) 精度执行。

    如果没有匹配的行,则 BIT_OR()返回一个中性值(所有位设置为 0)。

  • BIT_XOR(expr)

    返回XOR中所有位的按位expr。计算以 64 位 ( BIGINT) 精度执行。

    如果没有匹配的行,则 BIT_XOR()返回一个中性值(所有位设置为 0)。

  • COUNT(expr)

    返回语句检索的行中非NULL 值 的数量的计数。结果是一个 值。 exprSELECTBIGINT

    如果没有匹配的行,则 COUNT()返回 0

    mysql> SELECT student.student_name,COUNT(*)
           FROM student,course
           WHERE student.student_id=course.student_id
           GROUP BY student_name;

    COUNT(*)有点不同,因为它返回检索到的行数,无论它们是否包含 NULL值。

    对于诸如 之类的事务性存储引擎 InnoDB,存储准确的行数是有问题的。多个事务可能同时发生,每个事务都可能影响计数。

    InnoDB不保留表中行的内部计数,因为并发事务可能同时 看到不同数量的行。因此,SELECT COUNT(*) 语句只对当前事务可见的行进行计数。

    要处理一条SELECT COUNT(*)语句, InnoDB扫描表的索引,如果索引不完全在缓冲池中,则需要一些时间。为了更快地计数,创建一个计数器表并让您的应用程序根据它所做的插入和删除更新它。但是,在数千个并发事务正在启动对同一个计数器表的更新的情况下,此方法可能无法很好地扩展。如果近似行数足够,请使用 SHOW TABLE STATUS.

    InnoDB以相同的方式处理SELECT COUNT(*)SELECT COUNT(1) 操作。没有性能差异。

    对于MyISAM表, 如果从一个表中检索,没有检索到其他列,并且没有 子句,COUNT(*)则优化为非常快速地返回 。例如: SELECTWHERE

    mysql> SELECT COUNT(*) FROM student;

    此优化仅适用于MyISAM 表,因为为该存储引擎存储了精确的行数并且可以非常快速地访问。 COUNT(1)如果第一列定义为 ,则仅进行相同的优化NOT NULL

  • COUNT(DISTINCT expr,[expr...])

    返回具有不同非NULL expr 值的行数的计数。

    如果没有匹配的行,则 COUNT(DISTINCT)返回 0

    mysql> SELECT COUNT(DISTINCT results) FROM student;

    NULL在 MySQL 中,您可以通过给出一个表达式列表 来获取不包含的不同表达式组合的数量。在标准 SQL 中,您必须将 COUNT(DISTINCT ...).

  • GROUP_CONCAT(expr)

    此函数返回一个字符串结果,其中包含NULL来自组的连接的非值。NULL如果没有非NULL值,它会返回 。完整语法如下:

    GROUP_CONCAT([DISTINCT] expr [,expr ...]
                 [ORDER BY {unsigned_integer | col_name | expr}
                     [ASC | DESC] [,col_name ...]]
                 [SEPARATOR str_val])
    mysql> SELECT student_name,
             GROUP_CONCAT(test_score)
           FROM student
           GROUP BY student_name;

    或者:

    mysql> SELECT student_name,
             GROUP_CONCAT(DISTINCT test_score
                          ORDER BY test_score DESC SEPARATOR ' ')
           FROM student
           GROUP BY student_name;

    在 MySQL 中,您可以获得表达式组合的连接值。要消除重复值,请使用 DISTINCT子句。要对结果中的值进行排序,请使用ORDER BY子句。要以相反的顺序排序,请将(降序)关键字添加到子句DESC 中作为排序依据的列的名称。ORDER BY默认为升序;这可以使用ASC关键字明确指定。组中值之间的默认分隔符是逗号 ( ,)。要明确指定分隔符,请使用SEPARATOR后跟应插入组值之间的字符串文字值。要完全消除分隔符,请指定 SEPARATOR ''.

    结果被截断为系统变量给定的最大长度,group_concat_max_len 系统变量的默认值为 1024。该值可以设置得更高,但返回值的有效最大长度受 的值限制 max_allowed_packet。在运行时更改值的语法 group_concat_max_len如下,其中val 是一个无符号整数:

    SET [GLOBAL | SESSION] group_concat_max_len = val;

    返回值是非二进制或二进制字符串,具体取决于参数是非二进制字符串还是二进制字符串。结果类型为TEXTor BLOB除非 group_concat_max_len小于或等于 512,在这种情况下结果类型为 VARCHARor VARBINARY

    如果GROUP_CONCAT()mysql客户端中调用,则二进制字符串结果使用十六进制表示法显示,具体取决于 --binary-as-hex. 有关该选项的更多信息,请参阅第 4.5.1 节,“mysql — MySQL 命令行客户端”

    另请参阅CONCAT()CONCAT_WS()第 12.8 节,“字符串函数和运算符”

  • MAX([DISTINCT] expr)

    返回 的最大值 exprMAX()可能需要一个字符串参数;在这种情况下,它返回最大的字符串值。参见第 8.3.1 节,“MySQL 如何使用索引”DISTINCT关键字可用于查找 的不同值的最大值 , expr但是,这会产生与省略 相同的结果DISTINCT

    如果没有匹配的行,则 MAX()返回 NULL

    mysql> SELECT student_name, MIN(test_score), MAX(test_score)
           FROM student
           GROUP BY student_name;

    对于MAX(),MySQL 当前通过字符串值而不是字符串在集合中的相对位置来比较ENUM和 列。SET这与ORDER BY 比较它们的方式不同。

  • MIN([DISTINCT] expr)

    返回 的最小值 exprMIN()可能需要一个字符串参数;在这种情况下,它返回最小字符串值。参见第 8.3.1 节,“MySQL 如何使用索引”DISTINCT关键字可用于查找 的不同值中的最小值 , expr但是,这会产生与省略 相同的结果DISTINCT

    如果没有匹配的行,则 MIN()返回 NULL

    mysql> SELECT student_name, MIN(test_score), MAX(test_score)
           FROM student
           GROUP BY student_name;

    对于MIN(),MySQL 当前通过字符串值而不是字符串在集合中的相对位置来比较ENUM和 列。SET这与ORDER BY 比较它们的方式不同。

  • STD(expr)

    返回 的总体标准差 exprSTD()是标准 SQL 函数的同义词 STDDEV_POP(),作为 MySQL 扩展提供。

    如果没有匹配的行,则 STD()返回 NULL

  • STDDEV(expr)

    返回 的总体标准差 exprSTDDEV()是标准 SQL 函数的同义词 STDDEV_POP(),提供它是为了与 Oracle 兼容。

    如果没有匹配的行,则 STDDEV()返回 NULL

  • STDDEV_POP(expr)

    expr返回(的平方根 ) 的总体标准差 VAR_POP()。您还可以使用 STD()or STDDEV(),它们等效但不是标准 SQL。

    如果没有匹配的行,则 STDDEV_POP()返回 NULL

  • STDDEV_SAMP(expr)

    返回样本标准偏差 expr(的平方根 VAR_SAMP()

    如果没有匹配的行,则 STDDEV_SAMP()返回 NULL

  • SUM([DISTINCT] expr)

    返回 的总和expr。如果返回集没有行,则SUM() 返回NULLDISTINCT关键字可用于仅对 的不同值求和 expr

    如果没有匹配的行,则 SUM()返回 NULL

  • VAR_POP(expr)

    返回 的总体标准方差 expr。它将行视为整个总体,而不是样本,因此它以行数作为分母。您也可以使用 VARIANCE(),它等效但不是标准 SQL。

    如果没有匹配的行,则 VAR_POP()返回 NULL

  • VAR_SAMP(expr)

    返回 的样本方差 expr。也就是说,分母是行数减一。

    如果没有匹配的行,则 VAR_SAMP()返回 NULL

  • VARIANCE(expr)

    返回 的总体标准方差 exprVARIANCE()是标准 SQL 函数的同义词 VAR_POP(),作为 MySQL 扩展提供。

    如果没有匹配的行,则 VARIANCE()返回 NULL