# 12.20.1 聚合函数描述

本节介绍对值集进行操作的聚合函数。它们通常与通过...分组子句将值分组为子集。

表 12.25 聚合函数

姓名 描述
平均() 返回参数的平均值
位与() 按位返回 AND
位或() 按位或返回
BIT_XOR() 返回按位异或
数数() 返回返回的行数
计数(不同) 返回多个不同值的计数
GROUP_CONCAT() 返回一个连接的字符串
JSON_ARRAYAGG() 将结果集作为单个 JSON 数组返回
JSON_OBJECTAGG() 将结果集作为单个 JSON 对象返回
最大限度() 返回最大值
最小() 返回最小值
性病() 返回总体标准差
STDDEV() 返回总体标准差
STDDEV_POP() 返回总体标准差
STDDEV_SAMP() 返回样本标准差
和() 返回总和
VAR_POP() 返回总体标准方差
VAR_SAMP() 返回样本方差
方差() 返回总体标准方差

除非另有说明,否则聚合函数会忽略空值价值观。

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

大多数聚合函数都可以用作窗口函数。可以以这种方式使用的那些在其语法描述中表示为[*over_clause*],代表一个可选的超过条款。*over_clause*描述在第 12.21.2 节,“窗口函数概念和语法”,其中还包括有关窗口函数使用的其他信息。

对于数值参数,方差和标准差函数返回一个双倍的价值。这和()平均()函数返回一个十进制精确值参数的值(整数或十进制) 和一个双倍的近似值参数的值 (漂浮要么双倍的)。

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

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

功能如和()要么平均()如果需要,期望数字参数将参数转换为数字。为了要么枚举值,强制转换操作会导致使用基础数值。

位与(),位或(), 和BIT_XOR()聚合函数执行位操作。在 MySQL 8.0 之前,需要位函数和运算符大整数(64 位整数)参数并返回大整数值,因此它们的最大范围为 64 位。非-大整数参数被转换为大整数在执行操作之前,可能会发生截断。

在 MySQL 8.0 中,位函数和运算符允许二进制字符串类型参数 (二进制,变量, 和斑点types) 并返回一个类似类型的值,这使它们能够接受参数并产生大于 64 位的返回值。有关位操作的参数评估和结果类型的讨论,请参阅介绍性讨论第 12.13 节,“位函数和运算符”.

  • 平均([不同] *表达式*) [*over_clause*]

    返回平均值*表达式*.这清楚的选项可用于返回不同值的平均值*表达式*.

    如果没有匹配的行,平均()返回空值.

    此函数作为窗口函数执行,如果*over_clause存在。over_clause*如中所述第 12.21.2 节,“窗口函数概念和语法”;它不能与清楚的.

    mysql> SELECT student_name, AVG(test_score)
           FROM student
           GROUP BY student_name;
    
  • 位与(*表达式*) [*over_clause*]

    按位返回在所有位*表达式*.

    结果类型取决于函数参数值是否被评估为二进制字符串或数字:

    • 当参数值具有二进制字符串类型并且参数不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数值转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数值长度相同的二进制字符串。如果参数值的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。如果参数大小超过 511 字节,则ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      如果没有匹配的行,位与()返回与参数值具有相同长度的中性值(所有位设置为 1)。

    空值值不会影响结果,除非所有值都空值.在这种情况下,结果是与参数值具有相同长度的中性值。

    有关参数评估和结果类型的更多信息讨论,请参阅介绍性讨论第 12.13 节,“位函数和运算符”.

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

    从 MySQL 8.0.12 开始,此函数作为窗口函数执行,如果*over_clause存在。over_clause*如中所述第 12.21.2 节,“窗口函数概念和语法”.

  • 位或(*表达式*) [*over_clause*]

    按位返回要么在所有位*表达式*.

    结果类型取决于函数参数值是否被评估为二进制字符串或数字:

    • 当参数值具有二进制字符串类型并且参数不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数值转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数值长度相同的二进制字符串。如果参数值的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。如果参数大小超过 511 字节,则ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      如果没有匹配的行,位或()返回与参数值具有相同长度的中性值(所有位设置为 0)。

    空值值不会影响结果,除非所有值都空值.在这种情况下,结果是与参数值具有相同长度的中性值。

    有关参数评估和结果类型的更多信息讨论,请参阅介绍性讨论第 12.13 节,“位函数和运算符”.

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

    从 MySQL 8.0.12 开始,此函数作为窗口函数执行,如果*over_clause存在。over_clause*如中所述第 12.21.2 节,“窗口函数概念和语法”.

  • BIT_XOR(*表达式*) [*over_clause*]

    按位返回异或在所有位*表达式*.

    结果类型取决于函数参数值是否被评估为二进制字符串或数字:

    • 当参数值具有二进制字符串类型并且参数不是十六进制文字、位文字或空值文字。否则会进行数值计算,必要时将参数值转换为无符号 64 位整数。

    • 二进制字符串求值产生一个与参数值长度相同的二进制字符串。如果参数值的长度不相等,则ER_INVALID_BITWISE_OPERANDS_SIZE (opens new window)发生错误。如果参数大小超过 511 字节,则ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE (opens new window)发生错误。数值计算产生一个无符号的 64 位整数。

      如果没有匹配的行,BIT_XOR()返回与参数值具有相同长度的中性值(所有位设置为 0)。

    空值值不会影响结果,除非所有值都空值.在这种情况下,结果是与参数值具有相同长度的中性值。

    有关参数评估和结果类型的更多信息讨论,请参阅介绍性讨论第 12.13 节,“位函数和运算符”.

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

    从 MySQL 8.0.12 开始,此函数作为窗口函数执行,如果*over_clause存在。over_clause*如中所述第 12.21.2 节,“窗口函数概念和语法”.

  • 数数(*表达式*) [*over_clause*]

    返回非数的计数空值的值*表达式*在由 a 检索到的行中选择陈述。结果是一个大整数价值。

    如果没有匹配的行,数数()返回0.

    此函数作为窗口函数执行,如果*over_clause存在。over_clause*如中所述第 12.21.2 节,“窗口函数概念和语法”.

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

    数数(*)有点不同,它返回检索到的行数的计数,无论它们是否包含空值价值观。

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

    InnoDB不会保留表中的内部行数,因为并发事务可能同时“看到”不同数量的行。所以,选择计数(*)语句只计算对当前事务可见的行。

    从 MySQL 8.0.13 开始,从 * 中选择计数(*)tbl_name*查询性能InnoDB如果没有额外的子句,则表针对单线程工作负载进行了优化,例如在哪里要么通过...分组.

    InnoDB流程选择计数(*)通过遍历最小的可用二级索引来声明语句,除非索引或优化器提示指示优化器使用不同的索引。如果二级索引不存在,InnoDB流程选择计数(*)通过扫描聚集索引的语句。

    加工选择计数(*)如果索引记录不完​​全在缓冲池中,则语句需要一些时间。为了更快地计数,创建一个计数器表并让您的应用程序根据它所做的插入和删除来更新它。但是,在数千个并发事务正在启动对同一个计数器表的更新的情况下,此方法可能无法很好地扩展。如果近似的行数就足够了,请使用显示表状态.

    InnoDB把手选择计数(*)选择计数(1)以同样的方式进行操作。没有性能差异。

    为了MyISAM表,数数(*)如果选择从一个表中检索,没有其他列被检索,并且没有在哪里条款。例如:

    mysql> SELECT COUNT(*) FROM student;
    

    此优化仅适用于MyISAM表,因为为此存储引擎存储了准确的行数,并且可以非常快速地访问。计数(1)如果第一列定义为非空.

  • 计数(不同 *表达式*,[*表达式*...])

    返回具有不同非的行数的计数空值 *表达式*价值观。

    如果没有匹配的行,计数(不同)返回0.

    mysql> SELECT COUNT(DISTINCT results) FROM student;
    

    在 MySQL 中,您可以获得不包含的不同表达式组合的数量空值通过给出表达式列表。在标准 SQL 中,您必须将所有表达式串联起来计数(不同的...).

  • GROUP_CONCAT(*表达式*)

    此函数返回一个字符串结果,其中包含连接的非空值来自一个组的值。它返回无效的如果没有非-无效的价值观完整语法如下所示:

    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中,可以获得表达式组合的串联值。要消除重复值,请使用不同的条款要对结果中的值进行排序,请使用订购人条款要按相反顺序排序,请添加描述(降序)关键字设置为要在中排序的列的名称订购人条款默认为升序;可以使用ASC关键词。组中值之间的默认分隔符为逗号(,).要明确指定分隔符,请使用分离器后跟应插入组值之间的字符串文字值。要完全消除分隔符,请指定分隔符“.

    结果将被截断为组_concat_max_len系统变量,默认值为1024。虽然返回值的有效最大长度受最大允许包数.更改的值的语法组_concat_max_len运行时如下所示,其中*瓦尔*是无符号整数:

    SET [GLOBAL | SESSION] group_concat_max_len = val;
    

    返回值是非二进制或二进制字符串,具体取决于参数是非二进制还是二进制字符串。结果类型是文本斑点除非组_concat_max_len小于或等于512,在这种情况下,结果类型为瓦尔查尔VARBINARY.

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

    另见CONCAT()CONCAT_WS(): 第12.8节,“字符串函数和运算符”.

  • 雅格(*col_或_expr*) [*over_条款*]

    将结果集聚合为单个JSON其元素由行组成的数组。此数组中元素的顺序未定义。该函数作用于计算结果为单个值的列或表达式。退换商品无效的如果结果不包含行,或在发生错误时。

    从MySQL 8.0.14开始,如果*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

    mysql> SELECT o_id, attribute, value FROM t3;
    +------+-----------+-------+
    | o_id | attribute | value |
    +------+-----------+-------+
    |    2 | color     | red   |
    |    2 | fabric    | silk  |
    |    3 | color     | green |
    |    3 | shape     | square|
    +------+-----------+-------+
    4 rows in set (0.00 sec)
    
    mysql> SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes
         > FROM t3 GROUP BY o_id;
    +------+---------------------+
    | o_id | attributes          |
    +------+---------------------+
    |    2 | ["color", "fabric"] |
    |    3 | ["color", "shape"]  |
    +------+---------------------+
    2 rows in set (0.00 sec)
    
  • JSON_OBJECTAGG(*钥匙*, *价值*) [*over_条款*]

    将两个列名或表达式作为参数,第一个用作键,第二个用作值,并返回一个包含键值对的JSON对象。退换商品无效的如果结果不包含行,或在发生错误时。如果指定了任何键名,则会发生错误无效的或者参数的数量不等于2。

    从MySQL 8.0.14开始,如果*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

    mysql> SELECT o_id, attribute, value FROM t3;
    +------+-----------+-------+
    | o_id | attribute | value |
    +------+-----------+-------+
    |    2 | color     | red   |
    |    2 | fabric    | silk  |
    |    3 | color     | green |
    |    3 | shape     | square|
    +------+-----------+-------+
    4 rows in set (0.00 sec)
    
    mysql> SELECT o_id, JSON_OBJECTAGG(attribute, value)
         > FROM t3 GROUP BY o_id;
    +------+---------------------------------------+
    | o_id | JSON_OBJECTAGG(attribute, value)      |
    +------+---------------------------------------+
    |    2 | {"color": "red", "fabric": "silk"}    |
    |    3 | {"color": "green", "shape": "square"} |
    +------+---------------------------------------+
    2 rows in set (0.00 sec)
    

    **重复密钥处理。**当此函数的结果被规格化时,具有重复键的值将被丢弃。与MySQL保持一致JSON不允许重复密钥的数据类型规范,只有遇到的最后一个值与返回对象中的该密钥一起使用(“最后一个重复密钥获胜”)。这意味着对来自选择可能取决于返回行的顺序,但这并不能保证。

    当用作窗口函数时,如果帧中存在重复的关键点,则结果中只显示该关键点的最后一个值。如果订购人规范保证这些值具有特定的顺序。如果不是,则密钥的结果值是不确定的。

    考虑以下事项:

    mysql> CREATE TABLE t(c VARCHAR(10), i INT);
    Query OK, 0 rows affected (0.33 sec)
    
    mysql> INSERT INTO t VALUES ('key', 3), ('key', 4), ('key', 5);
    Query OK, 3 rows affected (0.10 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c, i FROM t;
    +------+------+
    | c    | i    |
    +------+------+
    | key  |    3 |
    | key  |    4 |
    | key  |    5 |
    +------+------+
    3 rows in set (0.00 sec)
    
    mysql> SELECT JSON_OBJECTAGG(c, i) FROM t;
    +----------------------+
    | JSON_OBJECTAGG(c, i) |
    +----------------------+
    | {"key": 5}           |
    +----------------------+
    1 row in set (0.00 sec)
    
    mysql> DELETE FROM t;
    Query OK, 3 rows affected (0.08 sec)
    
    mysql> INSERT INTO t VALUES ('key', 3), ('key', 5), ('key', 4);
    Query OK, 3 rows affected (0.06 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c, i FROM t;
    +------+------+
    | c    | i    |
    +------+------+
    | key  |    3 |
    | key  |    5 |
    | key  |    4 |
    +------+------+
    3 rows in set (0.00 sec)
    
    mysql> SELECT JSON_OBJECTAGG(c, i) FROM t;
    +----------------------+
    | JSON_OBJECTAGG(c, i) |
    +----------------------+
    | {"key": 4}           |
    +----------------------+
    1 row in set (0.00 sec)
    

    从上一个查询中选择的密钥是不确定的。如果查询不使用分组(不管怎样,它通常会强制执行自己的顺序)并且您更喜欢特定的键顺序,您可以调用JSON_OBJECTAGG()作为窗口函数,包括结束带有订购人对帧行施加特定顺序的规范。下面的例子展示了使用和不使用的情况订购人对于一些不同的框架规格。

    没有订购人,框架是整个分区:

    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER () AS json_object FROM t;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 4}  |
    | {"key": 4}  |
    | {"key": 4}  |
    +-------------+
    

    具有订购人,其中框架是默认的无界前一行和当前行之间的范围(按升序和降序排列):

    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER (ORDER BY i) AS json_object FROM t;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 3}  |
    | {"key": 4}  |
    | {"key": 5}  |
    +-------------+
    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER (ORDER BY i DESC) AS json_object FROM t;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 5}  |
    | {"key": 4}  |
    | {"key": 3}  |
    +-------------+
    

    具有订购人以及整个分区的明确框架:

    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER (ORDER BY i
                ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
            AS json_object
           FROM t;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 5}  |
    | {"key": 5}  |
    | {"key": 5}  |
    +-------------+
    

    要返回特定的键值(如最小或最大),请包含限度在适当的查询中。例如:

    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER (ORDER BY i) AS json_object FROM t LIMIT 1;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 3}  |
    +-------------+
    mysql> SELECT JSON_OBJECTAGG(c, i)
           OVER (ORDER BY i DESC) AS json_object FROM t LIMIT 1;
    +-------------+
    | json_object |
    +-------------+
    | {"key": 5}  |
    +-------------+
    

    看见JSON值的规范化、合并和自动包装,以获取更多信息和示例。

  • 最大值([不同]*expr*) [*over_条款*]

    返回的最大值*expr. 麦克斯()可以接受字符串参数;在这种情况下,它返回最大字符串值。看见第8.3.1节,“MySQL如何使用索引”这个不同的关键字可用于查找expr*然而,这会产生与省略相同的结果不同的.

    如果没有匹配的行,麦克斯()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”; 它不能与不同的.

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

    对于麦克斯(),MySQL目前正在进行比较枚举设置列的值,而不是字符串在集合中的相对位置。这与订购人比较它们。

  • 最小值([不同]*expr*) [*over_条款*]

    返回的最小值*expr. MIN()可以接受字符串参数;在这种情况下,它返回最小字符串值。看见第8.3.1节,“MySQL如何使用索引”这个不同的关键字可用于查找expr*然而,这会产生与省略相同的结果不同的.

    如果没有匹配的行,MIN()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”; 它不能与不同的.

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

    对于MIN(),MySQL目前正在进行比较枚举设置列的值,而不是字符串在集合中的相对位置。这与订购人比较它们。

  • 性病(*expr*) [*over_条款*]

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

    如果没有匹配的行,STD()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • 斯蒂夫(*expr*) [*over_条款*]

    返回的总体标准偏差*expr*. STDDEV()是标准SQL函数的同义词STDDEV_POP(),以便与Oracle兼容。

    如果没有匹配的行,STDDEV()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • STDDEV_POP(*expr*) [*over_条款*]

    返回的总体标准偏差*expr*(平方根)VAR_POP()).你也可以使用STD()STDDEV(),它们是等效的,但不是标准SQL。

    如果没有匹配的行,STDDEV_POP()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • STDDEV_SAMP(*expr*) [*over_条款*]

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

    如果没有匹配的行,STDDEV_SAMP()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • 总和([不同]*expr*) [*over_条款*]

    返回*expr.如果返回集没有行,SUM()返回无效的这个不同的关键字只能用于对expr*.

    如果没有匹配的行,SUM()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”; 它不能与不同的.

  • VAR_POP(*expr*) [*over_条款*]

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

    如果没有匹配的行,VAR_POP()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • VAR_SAMP(*expr*) [*over_条款*]

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

    如果没有匹配的行,VAR_SAMP()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.

  • 差异(*expr*) [*over_条款*]

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

    如果没有匹配的行,方差()返回无效的.

    如果出现以下情况,此函数将作为窗口函数执行:*over_条款他在场。over_条款*如中所述第12.21.2节,“窗口功能概念和语法”.