聚合函数
聚合函数对一组值进行计算,并返回单个的值。除了COUNT(*)外,聚合函数都会忽略NULL值。聚合函数通常与GROUP BY子句一起使用。
- 聚合函数的结果与数据输入顺序相关,不同的数据输入顺序会导致结果的精度差异。
m_db=# CREATE TABLE IF NOT EXISTS t1 (name VARCHAR(20), c1 INT(100), c2 FLOAT(7,5)); CREATE TABLE m_db=# INSERT INTO t1 VALUES m_db-# ('计算机', 666,-55.155), m_db-# ('计算机', 789,-15.593), m_db-# ('计算机', 928,-53.963), m_db-# ('计算机', 666,-54.555), m_db-# ('计算机', 666,-55.555), m_db-# ('数据库', 666,-55.155), m_db-# ('数据库', 789,-15.593), m_db-# ('数据库', 928,-53.963), m_db-# ('数据库', 666,-54.555), m_db-# ('数据库', 666,-55.555); INSERT 0 10 m_db=# select std(c1/c2) from t1; std ------------------- 15.02396266299967 (1 row) # ORDER BY改变了聚合函数的执行顺序,导致结果精度差异 m_db=# select std(c1/c2 order by c2) from t1; std -------------------- 15.023962662999669 (1 row) m_db=# select std(c1/c2) from t1 group by name; std -------------------- 15.023962662999669 15.023962662999669 (2 rows) # 与WITH ROLLUP使用,也会改变聚合函数的执行顺序,导致结果精度差异 m_db=# select std(c1/c2) from t1 group by name with rollup; std -------------------- 15.02396266299967 15.023962662999669 15.02396266299967 (3 rows) - 聚合函数与GROUP BY同时使用时,若推导类型为DECIMAL场景时,GaussDB保留完整精度的数据。
m_db=# SELECT avg(col_znumeric3/col_znumeric2) FROM fun_op_case_tb_1 WHERE id<=10 GROUP BY name; avg --------------- 1.45980942957 1.45980942957 1.45980942957 (3 rows) m_db=# SELECT sum(col_bit1/col_time2) FROM fun_op_case_tb_1 WHERE id<=10 GROUP BY name; sum -------- 0.0006 0.0006 0.0006 (3 rows)
AVG
AVG([ALL | DISTINCT] expr) [over_clause]
描述:返回输入expr的平均值,NULL值将被忽略。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:可以是TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、DECIMAL、FLOAT、DOUBLE。
返回值类型:
- 返回值类型视入参数据类型而定。当入参为精确值(INT、DECIMAL)时,返回DECIMAL;当入参为近似值(FLOAT、DOUBLE)时返回DOUBLE类型。
- 如果expr中的值均为NULL,则AVG()返回NULL。
- 如果指定ALL或者不指定ALL与DISTINCT,则返回expr中所有非空值的平均值。
- 如果指定DISTINCT,则返回expr中不同值的平均值。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT age, AVG(salary) FROM m_test GROUP BY (age); age | avg -----+-------- 1 | 1.6667 2 | (2 rows) m_db=# SELECT age, AVG(DISTINCT salary) FROM m_test GROUP BY (age); age | avg -----+-------- 1 | 1.5000 2 | (2 rows) m_db=# SELECT age, AVG(salary) OVER(PARTITION BY age ORDER by salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM m_test; age | avg -----+-------- 1 | 1.0000 1 | 1.6667 1 | 1.6667 1 | 1.6667 2 | 2 | (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
当输入是字符类型时,会触发字符类型到数值类型的隐式转换,并输出WARNING日志,导致性能变差。
m_db=# SELECT AVG('xxxx');
WARNING: Truncated incorrect double value: 'xxxx'
avg
-----
0
(1 row)
BIT_AND
BIT_AND([ALL] expr) [over_clause]
描述:返回expr中所有值的按位与,忽略NULL。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:BIT_AND需要使用BIGINT作为参数,其他类型的参数会被转换为BIGINT,并且可能发生截断。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则BIT_AND()返回一个中性值(所有位都被设置为1)。
- ALL为可选项,不影响结果。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT);
CREATE TABLE
m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL);
INSERT 0 6
m_db=# SELECT * FROM m_test;
age | salary
-----+--------
1 |
1 | 1
1 | 2
1 | 2
2 |
2 |
(6 rows)
m_db=# SELECT BIT_AND(ALL salary) FROM m_test GROUP BY age;
bit_and
----------------------
0
18446744073709551615
(2 rows)
m_db=# SELECT age, BIT_AND(salary) OVER(PARTITION BY age ORDER by salary ROWS CURRENT ROW) FROM m_test;
age | bit_and
-----+----------------------
1 | 1
1 | 2
1 | 2
1 | 18446744073709551615
2 | 18446744073709551615
2 | 18446744073709551615
(6 rows)
m_db=# DROP TABLE m_test;
DROP TABLE
当输入是字符类型时,会触发字符类型到数值类型的隐式转换,并输出WARNING日志,导致性能变差。
m_db=# SELECT BIT_AND('xxxx');
WARNING: Truncated incorrect INTEGER value: 'xxxx'
bit_and
---------
0
(1 row)
BIT_OR
BIT_OR([ALL] expr) [over_clause]
描述:返回expr中所有值的按位或,忽略NULL。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:BIT_OR需要使用BIGINT作为参数,其他类型的参数会被转换为BIGINT,并且可能发生截断。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则BIT_OR()返回一个中性值(所有位都被设置为0)。
- ALL为可选项,不影响结果。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT BIT_OR(ALL salary) FROM m_test GROUP BY age; bit_or -------- 3 0 (2 rows) m_db=# SELECT age, BIT_OR(salary) OVER(PARTITION BY age ORDER by salary ROWS CURRENT ROW) FROM m_test; age | bit_or -----+-------- 1 | 1 1 | 2 1 | 2 1 | 0 2 | 0 2 | 0 (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
当输入是字符类型时,会触发字符类型到数值类型的隐式转换,并输出WARNING日志,导致性能变差。
m_db=# SELECT BIT_OR('xxxx');
WARNING: Truncated incorrect INTEGER value: 'xxxx'
bit_or
--------
0
(1 row)
BIT_XOR
BIT_XOR([ALL] expr) [over_clause]
描述:返回expr中所有值的按位异或,忽略NULL。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:BIT_XOR需要使用BIGINT作为参数,其他类型的参数会被转换为BIGINT,并且可能发生截断。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则BIT_OR()返回一个中性值(所有位都被设置为0)。
- ALL为可选项,不影响结果。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT BIT_XOR(ALL salary) FROM m_test GROUP BY age; bit_xor --------- 1 0 (2 rows) m_db=# SELECT age, BIT_XOR(salary) OVER(PARTITION BY age ORDER by salary ROWS CURRENT ROW) FROM m_test; age | bit_xor -----+--------- 1 | 1 1 | 2 1 | 2 1 | 0 2 | 0 2 | 0 (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
当输入是字符类型时,会触发字符类型到数值类型的隐式转换,并输出WARNING日志,导致性能变差。
m_db=# SELECT BIT_XOR('xxxx');
WARNING: Truncated incorrect INTEGER value: 'xxxx'
bit_xor
---------
0
(1 row)
COUNT
- COUNT([ALL] expr)
参数类型:入参可以是任意类型。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则COUNT()返回0。
- ALL为可选项,不影响结果。
- COUNT(*)比较特殊,它返回expr中所有值的数量,无论其是否为NULL。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT COUNT(ALL salary) FROM m_test GROUP BY age; count ------- 3 0 (2 rows) m_db=# SELECT COUNT(*) FROM m_test GROUP BY age; count ------- 4 2 (2 rows) m_db=# DROP TABLE m_test; DROP TABLE
- COUNT(DISTINCT expr1 [, expr2, ..., exprN] )
参数类型:入参可以是任意类型。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则返回0。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT COUNT(DISTINCT salary) FROM m_test GROUP BY age; count ------- 2 0 (2 rows) m_db=# DROP TABLE m_test; DROP TABLE - COUNT(expr) over_clause
描述:返回根据over_clause分区的expr的非空总行数,若输入为空,输出NULL。指定了over_clause,此函数作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
返回值类型:
- 返回值类型为BIGINT。
- 如果expr中的值均为NULL,则返回0。
示例:
m_db=# CREATE TABLE count_t1(group_id INT, val INT); CREATE TABLE m_db=# INSERT INTO count_t1 VALUES(1,1),(1,2),(1, 3),(2, 4),(2, 5),(2, 6),(3,7),(3,8); INSERT 0 8 m_db=# SELECT group_id, val, COUNT(val) OVER(partition by group_id) FROM count_t1; groupid | val | count ---------+-----+------- 1 | 1 | 3 1 | 2 | 3 1 | 3 | 3 2 | 4 | 3 2 | 5 | 3 2 | 6 | 3 3 | 7 | 2 3 | 8 | 2 (8 rows) m_db=# DROP TABLE count_t1; DROP TABLE
GROUP_CONCAT
GROUP_CONCAT语法如下:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
描述:将expr中的各个值进行拼接,返回一个字符串结果,NULL值会被忽略。
- 指定DISTINCT时消除expr中的重复值。
- ORDER BY:通过指定列对expr中的值进行排序。
- ASC | DESC:ASC为升序排序,DESC为倒序排序,默认为升序排序。
- SEPARATOR:拼接字符串时使用的分隔符,默认为逗号","。
- 当同时指定DISTINCT和ORDER BY时,DISTINCT表达式必须包含ORDER BY表达式,否则会报错。
- GROUP_CONCAT(... ORDER BY 数字)不代表按照第几个参数的顺序,数字只是一个常量表达式,相当于不排序。
- 使用参数group_concat_max_len限制GROUP_CONCAT最大返回长度,超长截断,目前能返回的最大长度是1073741823。
返回值类型:TEXT或BLOB
示例:
m_db=# CREATE TABLE m_test(id INT, name CHAR); CREATE TABLE m_db=# INSERT INTO m_test VALUES (1, 'a'), (1, 'b'), (2, 'd'), (2, 'c'), (3, 'a'), (3, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; id | name ----+------ 1 | a 1 | b 2 | d 2 | c 3 | a 3 | (6 rows) m_db=# SELECT GROUP_CONCAT(name SEPARATOR '') FROM m_test; group_concat -------------- abdca (1 row) m_db=# SELECT GROUP_CONCAT(DISTINCT id, name ORDER BY id DESC) FROM m_test; group_concat ------------------ 3a,2c,2d,1a,1b (1 row) m_db=# DROP TABLE m_test; DROP TABLE
MAX
MAX([ALL | DISTINCT] expr) [over_clause]
描述:返回输入expr的最大值,NULL值将被忽略。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:任意数值、字符串、日期时间类型。
返回值类型:
- 返回值类型与参数数据类型相同,当参数非表字段时,max返回值类型和mysql 8.0保持一致,与mysql 5.7不一样。
- 如果expr中的值均为NULL,则MAX()返回NULL。
- 如果指定ALL或者不指定ALL与DISTINCT,则返回expr中所有非空值的最大值。
- 如果指定了DISTINCT,则返回expr中不同非空值的最大值,与不指定DISTINCT的结果相同。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT MAX(DISTINCT salary) FROM m_test GROUP BY age; max ----- 2 (2 rows) m_db=# SELECT age, MAX(salary) OVER(PARTITION BY age ORDER by salary ROWS CURRENT ROW) FROM m_test; age | max -----+----- 1 | 1 1 | 2 1 | 2 1 | 2 | 2 | (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
MIN
MIN([ALL | DISTINCT] expr) [over_clause]
描述:返回输入expr的最小值,NULL值将被忽略。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:任意数值、字符串、日期时间类型。
返回值类型:
- 返回值类型与参数数据类型相同,当参数非表字段时,min返回值类型和MySQL 8.0保持一致,与MySQL 5.7不一样。
- 如果expr中的值均为NULL,则MIN()返回NULL。
- 如果指定ALL或者不指定ALL与DISTINCT,则返回expr中所有非空值的最小值。
- 如果指定了DISTINCT,则返回expr中不同非空值的最小值,与不指定DISTINCT的结果相同。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT MIN(DISTINCT salary) FROM m_test GROUP BY age; min ----- 1 (2 rows) m_db=# SELECT age, MIN(salary) OVER(PARTITION BY age ORDER by salary ROWS CURRENT ROW) FROM m_test; age | min -----+----- 1 | 1 1 | 2 1 | 2 1 | 2 | 2 | (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
SUM
SUM([ALL | DISTINCT] expr) [over_clause]
描述:返回输入expr的和,NULL值将被忽略。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
参数类型:可以是TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT、DECIMAL、FLOAT、DOUBLE。
返回值类型:
- 返回值类型视入参数据类型而定。当入参为精确值(INT、DECIMAL)时,返回DECIMAL;当入参为近似值(FLOAT、DOUBLE)时返回DOUBLE类型。
- 如果expr中的值均为NULL,则SUM()返回NULL。
- 如果指定ALL或者不指定ALL与DISTINCT,则返回expr中所有非空值的和。
- 如果指定DISTINCT,则返回expr中不同非空值的和。
示例:
m_db=# CREATE TABLE m_test(age INT, salary INT); CREATE TABLE m_db=# INSERT INTO m_test VALUES(1, NULL), (1, 1), (1, 2), (1, 2), (2, NULL), (2, NULL); INSERT 0 6 m_db=# SELECT * FROM m_test; age | salary -----+-------- 1 | 1 | 1 1 | 2 1 | 2 2 | 2 | (6 rows) m_db=# SELECT age, SUM(salary) FROM m_test GROUP BY (age); age | sum -----+----- 1 | 5 2 | (2 rows) m_db=# SELECT age, SUM(DISTINCT salary) FROM m_test GROUP BY (age); age | sum -----+----- 1 | 3 2 | (2 rows) m_db=# SELECT age, SUM(salary) OVER(PARTITION BY age ORDER by salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM m_test; age | sum -----+----- 1 | 1 1 | 3 1 | 5 1 | 5 2 | 2 | (6 rows) m_db=# DROP TABLE m_test; DROP TABLE
当输入是字符类型时,会触发字符类型到数值类型的隐式转换,并输出WARNING日志,导致性能变差。
m_db=# SELECT SUM('xxxx');
WARNING: Truncated incorrect double value: 'xxxx'
sum
-----
0
(1 row)
STD
STD(str) [over_clause]
描述:计算所有非NULL输入值的总体标准差并返回结果。如果指定了over_clause,此函数将作为窗口函数进行执行。over_clause参数说明请参见窗口函数说明。
返回值类型:DOUBLE
示例:
m_db=# CREATE TABLE students (name VARCHAR(20) NOT NULL, math INT);
CREATE TABLE
m_db=# INSERT INTO students (name, math) VALUES('a', 80),('b', 85),('c', 90),('d', 95),('e', 88),('f', 92),('g', 86),('h', 89),('i', 91),('j', 87);
INSERT 0 10
m_db=# SELECT STD(math) AS std_math FROM students;
std_math
--------------------
3.9509492530276824
(1 row)
m_db=# SELECT name, STD(math) OVER(ORDER by math ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM students;
name | std
------+--------------------
a | 0
b | 2.5
g | 2.6246692913372693
j | 2.6925824035672505
e | 2.7856776554368228
h | 2.9107081994288277
c | 3.063944369932457
i | 3.2403703492039275
f | 3.4354721852756214
d | 3.9509492530276806
(10 rows)
m_db=# DROP TABLE students;
DROP TABLE