本文中,我们将学习如何使用PostgreSQL聚合函数,例如
AVG()
,COUNT()
,MIN()
,MAX()
, 和SUM()
,以及ARRAY_AGG
和STRING_AGG
.
?PostgreSQL Aggregate Functions
?PostgreSQL 聚合函数简介
聚合函数对一组行执行计算并返回单行。PostgreSQL提供了所有标准SQL的聚合函数,如下所示:
AVG()
– 返回平均值。COUNT()
– 返回值的数量。MAX()
– 返回最大值。MIN()
– 返回最小值。SUM()
– 返回所有或不同值的总和。
我们经常将聚合函数与SELECT
声明中的GROUP BY
子句一起使用。在这些情况下,GROUP BY
子句将结果集分为几组行,聚合函数对每组执行计算,例如最大值、最小值、平均值等。
?只能在以下子句中将聚合函数用作表达式:
SELECT
子句.HAVING
子句.
?PostgreSQL AVG 方法
?前言: 在本文中,我们将学习如何使用PostgreSQL
AVG()
函数计算平均值。
?PostgreSQL AVG()
函数简介
AVG ()
函数是在PostgreSQL中最常用的聚合函数之一。AVG ()
函数允许我们计算集合的平均值。
AVG ()
的语法功能如下:
AVG(column)
我们可以在select
子句和having
子句中使用AVG ()
功能。
让我们看看一些使用AVG函数的例子。
?PostgreSQL AVG()
函数示例
如果你想查询score
字段的平均值,我们可以使用SELECT AVG(score)
语句,代码如下:
SELECT AVG(score)
FROM score;
avg
--------------------
63.0000000000000000
(1 row)
为了使输出更具可读性,我们可以使用cast运算符,如下所示:
SELECT AVG(amount)::numeric(10,2)
FROM score;
avg
------
63.00
(1 row)
?PostgreSQL AVG()
函数和 DISTINCT
关键字一起使用
计算集合中不同值的平均值, 我们可以使用DISTINCT
关键字,如下所示:
AVG(DISTINCT score)
以下查询返回客户的平均amount。因为我们使用DISTINCT,PostgreSQL仅采用唯一数值并计算平均值。
SELECT AVG(DISTINCT score)::numeric(10,2)
FROM score;
avg
------
75.27
我们可以发现查询结果和上一个不使用DISTINCT的sql不同。
?PostgreSQLAVG()
函数和 SUM
函数
以下查询同时使用AVG
和SUM
计算amount
总和与amount
平均值的函数。
SELECT
AVG(score)::numeric(10,2),
SUM(score)::numeric(10,2)
FROM
score;
avg | sum
------+----------
63.14| 61312.04
(1 row)
?PostgreSQLAVG()
函数和 GROUP BY
子句
要计算分组的平均值,请使用AVG()
功能与GROUP BY
子句。首先,GROUP BY
子句将表的行划分为组,然后AVG()
函数将应用于每个组。
以下是使用GROUP BY
子句和 AVG()
函数计算每个学生平均分数的示例
SELECT
student_id,
student_name,
AVG (score)::NUMERIC(10,2)
FROM
score
INNER JOIN student USING(student_id)
GROUP BY
student_id
ORDER BY
student_id;
在查询中,我们使用INNER JOIN
将student
表加入了score
表。我们通过使用GROUP BY
子句和 AVG()
函数计算每个学生平均分数。
?PostgreSQLAVG()
函数和 HAVING
子句
我们可以在HAVING
子句中使用AVG()
函数根据特定条件过滤。例如,对于所有学生,我们可以获得平均分数超过60的学生。以下是查询示例:
SELECT
student_id,
student_name,
AVG (score)::NUMERIC(10,2)
FROM
score
INNER JOIN student USING(student_id)
GROUP BY
student_id
HAVING
AVG (score) >= 60
ORDER BY
student_id;
此查询与上面的查询类似,并带有一个附加的HAVING子句。我们使用GROUP BY
功能在HAVING
子句过滤平均数量大于或等于60的分组数据。
?PostgreSQL AVG()
函数 NULL
让我们看看 AVG()
函数当遇到为NULL的数据时会是什么效果。
首先,创建表命名lpl
。
CREATE TABLE lpl (
id serial PRIMARY KEY,
rank INTEGER
);
第二,插入一些示例数据:
INSERT INTO lpl (rank)
VALUES
(899),
(NULL),
(996);
lpl表的数据如下:
SELECT * FROM lpl;
第三,使用AVG ()
函数计算rank
列中的平均值。
SELECT AVG(rank)::numeric(10,2)
FROM lpl;
avg
-------
947.50
它返回947.50
, 这意味着AVG ()
函数忽略NULL
值。
?PostgreSQL COUNT 方法
?前言: 在本文中,我们将学习如何使用PostgreSQL
COUNT()
函数计数。
?PostgreSQL COUNT()
方法概述
COUNT()
函数是一个聚合函数;它允许我们获取与查询的特定条件匹配的行数。
以下小节说明了各种使用COUNT()
的方法。
COUNT(*)
COUNT(*)
方法 返回 SELECT
查询出来的行数, 包括NULL和重复项。
SELECT
COUNT(*)
FROM
table_name
WHERE
condition;
当我们应用COUNT(*)
于整个表,PostgreSQL必须按顺序扫描整个表。
如果我们在大表上运行COUNT(*)
,查询将会很慢。这与PostgreSQL MVCC实现有关。因为多个事务同时看到不同状态的数据,所以没有直接的办法使COUNT(*)
函数对整个表进行计数,因此PostgreSQL必须扫描所有行来获取此表的计数结果。
COUNT(column)
类似COUNT(*)
功能,COUNT(column)
函数返回SELECT
查询出来的行数。然而,它没有考虑column
中的null
。
SELECT
COUNT(column)
FROM
table_name
WHERE
condition;
COUNT(DISTINCT column)
COUNT(DISTINCT column)
:返回查询出来的不重复且不为空的列的行数。
SELECT
COUNT(DISTINCT column)
FROM
table_name
WHERE
condition;
我们经常使用COUNT()
函数和GROUP BY
子句返回每个组的项数。例如,我们可以使用COUNT()
与GROUP BY
子句返回每个学生每门课程的分数。
?PostgreSQL COUNT()
方法示例
我们还是使用分数表,表结构如下
?1) PostgreSQL COUNT(*)
示例
以下语句使用COUNT(*)
函数返回score
表格行数:
SELECT
COUNT(*)
FROM
score;
输出如下:
COUNT
--------------------
1024
(1 row)
?2) PostgreSQL COUNT(DISTINCT column)
示例
要获得学生获得的不同成绩,我们可以使用COUNT(DISTINCT score)
函数,如以下示例所示:
SELECT
COUNT (DISTINCT score)
FROM
score;
输出如下:
COUNT
--------------------
512
(1 row)
?PostgreSQL COUNT()
和GROUP BY
子句 示例
要获得学生的课程成绩数,我们可以使用GROUP BY
子句根据student_id将学生分组,并使用COUNT()
函数计算每个组的付款。
以下是查询示例:
SELECT
student_id,
COUNT (student_id)
FROM
score
GROUP BY
student_id;
输出如下:
id | count
1 | 1
2 | 1
3 | 1
...
(512 row)
?PostgreSQL COUNT()
和HAVING
子句 示例
我们可以使用COUNT
功能在HAVING
子句将特定条件应用于组中计数。例如,以下语句查找成绩超过5门课程的学生:
SELECT
student_id,
COUNT (student_id)
FROM
score
GROUP BY
student_id
HAVING
COUNT (student_id) > 5;
输出如下:
id | count
12 | 7
24 | 10
48 | 32
...
(15 row)
?PostgreSQL MAX 方法
?前言:在本文中,我们将学习如何使用PostgreSQL
MAX()
函数求最大值。
?PostgreSQL MAX 函数简介
PostgreSQLMAX
函数是一个聚合函数,它返回一组值中的最大值。MAX
函数在许多情况下是有用的。例如,我们可以使用MAX
函数寻找成绩最高的学生或寻找通过课程最多的学生等功能。
MAX
函数的语法如下:
MAX(expression);
我们不仅可以在SELECT
子句中使用MAX
函数,也可以在WHERE
和HAVING
子句中使用,接下来,让我们看一些使用MAX
函数的示例。
?PostgreSQL MAX 方法示例
本次示例使用表结构如下
使用MAX
函数从score表中寻找成绩最高的数据
SELECT MAX(score)
FROM score;
输出如下:
max
--------------------
100
(1 row)
子查询中的PostgreSQL MAX函数
为了获得最高的分数,我们可以使用子查询如下所示:
SELECT * FROM score
WHERE score = (
SELECT MAX (score)
FROM score
);
首先,子查询使用MAX()
函数返回最高分数,然后外部查询选择分数等于从子查询返回的最高分数的所有行。
输出如下:
student_id | score
--------------------
12 | 100
(1 row)
PostgreSQL MAX 函数和 GROUP BY 子句
我们可以一起使用MAX
函数GROUP BY
子句以获取每个组的最大值。例如,以下查询获取每个用户的最高分数。
SELECT
student_id,
MAX (score)
FROM
score
GROUP BY
student_id;
输出如下:
student_id | score
--------------------
12 | 100
19 | 100
27 | 100
...
(100+ row)
PostgreSQL MAX 函数和 HAVING 子句
如果使用MAX()
函数和HAVING
子句,我们可以为组应用筛选器。
例如,以下查询仅选择每个学生取得的最高成绩,并且成绩大于95
。
SELECT
student_id,
MAX (score)
FROM
score
GROUP BY
student_id
HAVING MAX(score) > 95;
输出如下:
student_id | score
--------------------
1 | 98
10 | 96
12 | 100
15 | 99
19 | 100
23 | 98
27 | 100
...
(500+ row)
?从两个或多个列中查找最大值
首先,创建新表命名ranks
它由四列组成: 第一列存储用户id,其他三列存储从1到3的排名。
DROP TABLE IF EXISTS ranks;
CREATE TABLE ranks (
user_id INT PRIMARY KEY,
rank_1 INT NOT NULL,
rank_2 INT NOT NULL,
rank_3 INT NOT NULL
);
第二,插入样本数据进入ranks
表如下:
INSERT INTO ranks
VALUES
(1, 6, 3, 5),
(2, 2, 8, 5),
(3, 5, 9, 8);
如何获得每个用户的最大排名,如下面的屏幕截图所示:
为了实现这一点,你使用GREATEST()
函数代替MAX()
函数。GREATEST
函数从值列表中返回最大值。
SELECT
user_id,
GREATEST (rank_1, rank_2, rank_3) AS largest_rank
FROM
ranks;
?PostgreSQL MIN 方法
?前言:在本文中,我们将学习如何使用PostgreSQL
MIN()
函数求最小值。
?PostgreSQL MIN 函数介绍
PostgreSQLMIN
函数是一个聚合函数,它返回一组值中的最小值。
要查找表的列中的最小值,请将列的名称传递给MIN()
函数。列的数据类型的可以是number,string,或任何类似类型。
MIN
函数的语法如下:
SELECT
MIN(expression)
FROM
table_expression
...;
与 AVG()
, COUNT()
,SUM()
方法不同, MIN
函数不受DISTINCT
的影响。
?PostgreSQL MIN() 方法示例
我们将使用score
,counse_category
,以及course
表来用于演示,这三个表的结构如下所示。
?1) 在SELECT子句中使用PostgreSQL MIN函数
以下示例使用MIN函数从score表获取学生的最低成绩。
SELECT
MIN (score)
FROM
score;
输出如下:
score
--------
0
(1 row)
查询返回0,这是最低分。
?2) 在子查询中使用PostgreSQL MIN函数
要获取成绩的课程,请使用以下查询:
SELECT
course_id,
score
FROM
score
WHERE
score = (
SELECT MIN(score)
FROM score
);
输出如下:
course_id|score
---------|-------
10086 |0
(1 row)
它是如何工作的?
- 首先,子查询选择最低分数。
- 然后,外部查询选择分数等于子查询返回的最低分数的课程。
?3) 将PostgreSQL MIN函数与GROUP BY子句结合使用
实际上,我们会经常使用MIN
函数GROUP BY
子句查找每个组中的最小值。
以下语句使用MIN
函数和GROUP BY
子句按课程类别查找课程的最低分:
SELECT
name course,
MIN(score) score
FROM category
INNER JOIN course_category USING (category_id)
INNER JOIN score USING (course_id)
GROUP BY name
ORDER BY name;
输出如下:
course |score
---------|-------
Java |25
C++ |19
C |37
...
(17 row)
?4) 将PostgreSQL MIN函数与HAVING子句结合使用
可以使用MIN函数在HAVING
子句筛选与特定条件匹配组的最小值。
以下查询查找使用MIN()
方法以查找按类别分组的课程的最低成绩,并且最低成绩大于30。
SELECT
name course,
MIN(score) score
FROM category
INNER JOIN course_category USING (category_id)
INNER JOIN score USING (course_id)
GROUP BY name
HAVING MIN(score) > 30
ORDER BY name;
输出如下:
course |score
---------|-------
C |37
(1 row)
?5) 将PostgreSQL MIN函数与其他聚合函数结合使用
可以同时使用MIN()
和其他聚合函数,例如同一查询中的MIN()
函数和MAX()
函数。
以下示例使用MIN()
和MAX()
按课程分类查找最高和最低分数的课程:
SELECT
name course,
MIN(score) min_score
MAX(score) max_score
FROM category
INNER JOIN course_category USING (category_id)
INNER JOIN score USING (course_id)
GROUP BY name
ORDER BY name;
输出如下:
course |minscore|maxscore
---------|--------|-------
C |37 |100
C++ |19 |100
Java |25 |100
...
(17 row)
?6) 从两个或多个列中查找最小值
假设,你有以下ranks
表:
CREATE TABLE ranks (
user_id INT PRIMARY KEY,
rank_1 int4 NOT NULL,
rank_2 int4 NOT NULL,
rank_3 int4 NOT NULL
);
插入一些数据
INSERT INTO ranks
VALUES
(1, 6, 3, 5),
(2, 2, 8, 5),
(3, 5, 9, 8);
假设我们需要为每个用户找到最小排名:
在这种情况下,我们不能使用MIN()
方法,因为MIN()
函数应用于行,而不是列。要查找两列或更多列的最小值,请使用LEAST()
方法:
使用以下语句查询返回我们预期的结果:
SELECT
user_id,
LEAST (rank_1, rank_2, rank_3) AS lowest_rank
FROM
ranks;
?总结
- 使用
MIN()
函数查找一组值中的最低值。 - 使用
MIN()
与GROUP BY
子句查找一组值中的最小值。 - 使用
LEAST()
函数查找列之间的最小值。
?PostgreSQL SUM 方法
?前言:在本文中,我们将学习如何使用PostgreSQL
SUM ()
函数计算一组值的总和。
?PostgreSQL SUM() 函数简介
The PostgreSQLSUM()
是一个聚合函数,它返回值或不同值的总和。
SUM()
函数的语法如下:
SUM(DISTINCT expression)
SUM()
函数忽略null
。这意味着SUM()
在计算中不考虑null
。
如果使用DISTINCT
关键字,SUM()
函数计算去重值的总和。
例如,没有DISTINCT
,SUM()
1、1、8和2将返回12。当独特的选项可用,SUM()
计算1、 1、8和2将返回11 (1 + 8 + 2)。它引入一个重复值 (1)。
如果我们在SELECT
语句中使用SUM
方法,它返回NULL
而不是零,以防SELECT
不返回任何行。
?PostgreSQL SUM() 方法示例
本次示例使用表结构如下
?1) 在SELECT语句中使用PostgreSQL SUM() 函数示例
以下语句使用SUM()函数计算student_id为 10086的总成绩。
SELECT SUM (score) AS total
FROM score
WHERE student_id = 10086;
total
-------
null
(1 row)
因为score表没有 student_id = 10086的数据,SUM()函数返回一个null。
如果找不到匹配的行时,你想要SUM()
函数返回零而不是null,请使用COALESCE
方法。
COALESCE
函数返回第一个非null参数。换句话说,如果第一个参数为null,COALESCE
函数会返回下一个非空值。
以下查询说明了如何使用SUM()
函数和:COALESCE()
函数:
SELECT COALESCE(SUM(score),0) AS total
FROM score
WHERE student_id = 10086;
输出如下
total
-------
0
(1 row)
?2) 将PostgreSQL SUM() 函数与GROUP BY子句结合使用
要计算每个学生的总成绩,请使用GROUP BY子句将表中的行分组并应用SUM ()
来计算每个组的总分。
以下示例使用sum()函数和GROUP BY分组计算每个学生的总分数
SELECT
student_id,
SUM (score) AS total
FROM
score
GROUP BY
student_id
ORDER BY total;
输出如下
student_id|total
----------|-------
1 |726
2 |520
3 |250
4 |957
5 |4396
6 |2200
...
(369 row)
以下查询返回成绩最高的前五名学生:
SELECT
student_id,
SUM (score) AS total
FROM
score
GROUP BY
student_id
ORDER BY total DESC
LIMIT 5;
输出如下
student_id|total
----------|-------
369 |10086
5 |4396
6 |2200
22 |1777
4 |957
(5 row)
?3) 将PostgreSQL SUM函数与HAVING子句结合使用
要根据特定条件过滤组的总和,请在HAVING子句中使用SUM函数。
以下示例返回总分数超过1000分的学生:
SELECT
student_id,
SUM (score) AS total
FROM
score
GROUP BY
student_id
HAVING SUM(score) > 100
ORDER BY total DESC
输出如下
student_id|total
----------|-------
369 |10086
5 |4396
6 |2200
22 |1777
(4 row)
?4) 将PostgreSQL SUM与表达式结合使用
假设,你有以下ranks
表:
CREATE TABLE ranks (
user_id INT PRIMARY KEY,
rank_1 int4 NOT NULL,
rank_2 int4 NOT NULL,
rank_3 int4 NOT NULL
);
插入一些数据
INSERT INTO ranks
VALUES
(1, 6, 3, 5),
(2, 2, 8, 5),
(3, 5, 9, 8);
以下语句使用SUM ()
计算rank_1和rank_3之差总数的函数:
SELECT SUM(rank_1 - rank_3 )
FROM ranks;
sum
----
-5
(1 row)
它是如何工作的?
- 首先,获取rank_1和rank_3之差
- 第二,将之应用SUM()函数。
?总结
- 使用
SUM ()
函数计算值总和。 - 使用
DISTINCT
的用于计算不同值总和的选项。 - 使用
SUM ()
函数和GROUP BY
子句计算每个组的总和。
?PostgreSQL ARRAY_AGG 方法
?前言:在本文中,我们将学习如何使用PostgreSQL
ARRAY_AGG()
聚合函数从一组输入值返回数组。
?PostgreSQLARRAY_AGG()
功能简介
PostgreSQLARRAY_AGG()
函数是一个聚合函数,它接受一组值并返回一个数组,其中将集合中的每个值分配给数组的元素。
以下显示ARRAY_AGG()
语法:
ARRAY_AGG(expression [ORDER BY [sort_expression {ASC | DESC}], [...])
ARRAY_AGG()
接受返回对数组元素有效的任何类型的值的表达式。
ORDER BY
子句是可选子句。它指定在聚合中处理的行的顺序,该顺序确定结果数组中元素的顺序。
类似于其他聚合函数,例如 AVG()
, COUNT()
, MAX()
, MIN()
, SUM()
, ARRAY_AGG()
常常和ORDER BY
子句一起使用。
?PostgreSQLARRAY_AGG()
函数示例
为了演示,我们将使用course
,course_student
,以及student
表,表结构如下
?PostgreSQL ARRAY_AGG()
函数不和 ORDER BY
子句一起使用的示例
以下示例使用ARRAY_AGG()
函数返回每门课程的名称列表和报名学生列表:
SELECT
name,
ARRAY_AGG (student_name) students
FROM
course
INNER JOIN course_student USING (course_id)
INNER JOIN student USING (student_id)
GROUP BY
name
ORDER BY
name;
输出如下
name |students
----------|-------
C |["oz","oo","oq","oa"]
C++ |["oa","oz","oq","oo"]
Java |["oq","oo","oz","oa"]
Python |["oa","oo","oq","oz"]
(4 row)
如你所见,每门课程中的学生姓名都是随机排序的。要按姓氏或名字对学生进行排序,我们可以使用ORDER BY
子句中的ARRAY_AGG()
功能。
?PostgreSQL ARRAY_AGG()
函数和 ORDER BY
子句一起使用的示例
以下示例使用ARRAY_AGG()
函数返回每门课程的名称列表和报名学生列表,并根据学生姓名做出排序:
SELECT
name,
ARRAY_AGG (
student_name
ORDER BY
student_name
) students
FROM
course
INNER JOIN course_student USING (course_id)
INNER JOIN student USING (student_id)
GROUP BY
name
ORDER BY
name;
输出如下
name |students
----------|-------
C |["oa","oo","oq","oz"]
C++ |["oa","oo","oq","oz"]
Java |["oa","oo","oq","oz"]
Python |["oa","oo","oq","oz"]
(4 row)
我们可以按学生的名字对每门课程的学生列表进行倒序排序,如以下查询所示:
SELECT
name,
ARRAY_AGG (
student_name
ORDER BY
student_name DESC
) students
FROM
course
INNER JOIN course_student USING (course_id)
INNER JOIN student USING (student_id)
GROUP BY
name
ORDER BY
name;
?PostgreSQL STRING_AGG 方法
?前言:在本文中,我们将学习如何使用PostgreSQL
STRING_AGG()
函数连接字符串并在它们之间放置分隔符。
?PostgreSQLSTRING_AGG()
功能简介
PostgreSQLSTRING_AGG()
函数是一个聚合函数,它连接字符串列表并在它们之间放置分隔符。该函数不会在字符串末尾添加分隔符。
以下显示STRING_AGG()
函数的语法:
STRING_AGG ( expression, separator [order_by_clause] )
的STRING_AGG()
函数接受两个参数和一个可选参数order_by_clause
。
expression
是可以解析为字符串的任何有效表达式。如果使用字符串类型以外的其他类型,则需要显式地声明该类型的这些值为字符串类型。separator
是串联字符串的分隔符。
order_by_clause
是一个可选子句,指定串联结果的顺序。它具有以下形式:
ORDER BY expression1 {ASC | DESC}, [...]
STRING_AGG()
函数和ARRAY_AGG()
函数类似,但返回类型除外。STRING_AGG()
函数的返回类型是字符串,而ARRAY_AGG()
函数的返回类型是数组。
像其他聚合函数,例如 AVG()
, COUNT()
, MAX()
, MIN()
, SUM()
, STRING_AGG()
常常和ORDER BY
子句一起使用。
?PostgreSQL STRING_AGG()
function examples
为了演示,我们将使用course
,course_student
,以及student
表,表结构如下
示例: 使用STRING_AGG()
方法生成值的逗号分隔列表
此示例使用STRING_AGG()
函数course
表中的所有学生的名字列表:
SELECT
c.name,
STRING_AGG (s.student_name,','
ORDER BY
s.student_name
) students
FROM
course c
INNER JOIN course_student cs USING (course_id)
INNER JOIN student s USING (student_id)
GROUP BY
c.name;
输出如下
name |students
----------|-------
C |oz,oa,oq,oo
C++ |oz,oa,oq,oo
Java |oz,oa,oq,oo
Python |oz,oa,oq,oo
(4 row)