SQL学习四-聚集函数

SQL学习四-聚集函数

数据准备

原始数据:

IDNAMECLASSID
1xiaoming1
2xiaowang1
3xiaotian2
4xiaoming2
5xiaowang3
6xiaotian4

此外,还将往表中插入多条数据以满足学习聚合函数需要
插入数据如下:

IDNAMECLASSID
7xiaogang1
8xiaoqiang1
9xiaojing2
10xiaotie2
11wangqiang3
12wangwei3
13liming4
14liqiang4

插入语句如下:

INSERT INTO Student
VALUES 
(7, 'xiaogang', 1),
(8, 'xiaoqiang', 1),
(9, 'xiaojing', 2),
(10, 'xiaotie', 2),
(11, 'wangqiang', 3),
(12, 'wangwei', 3),
(13, 'liming', 4),
(14, 'liqiang', 4);

聚集函数种类

COUNT(): 计算总数
SUM(): 计算某分组的和
AVG(): 计算某分组的平均值
MAX():获取某分组的最大值
MIN(): 获取某分组的最小值
GROUP_CONCAT(), 按照分组,根据指定的属性进行拼接,然后添加到表的列中

COUNT

COUNT一般用于计数,中间可以放属性,放*,也可以放1等。
COUNT如果放属性,表示这个属性的行数,如果放1,可以理解成SQL语句在表中增加了tmp列,该列全部为1,然后计算1的个数,以上表为例:

COUNT(1):

IDNAMECLASSIDtmp
1xiaoming11
2xiaowang11
3xiaotian21
4xiaoming21
5xiaowang31
6xiaotian41
7xiaogang11
8xiaoqiang11
9xiaojing21
10xiaotie21
11wangqiang31
12wangwei31
13liming41
14liqiang41

然后COUNT(1)就会计算tmp列中1的数量,然后再添加一个属性COUNT(1)到上面,这时,COUNT(1)的结果就是当前表中1的数量,结果如下:

IDNAMECLASSIDtmpCOUNT(1)
1xiaoming1114
2xiaowang1114
3xiaotian2114
4xiaoming2114
5xiaowang3114
6xiaotian4114
7xiaogang1114
8xiaoqiang1114
9xiaojing2114
10xiaotie2114
11wangqiang3114
12wangwei3114
13liming4114
14liqiang4114

这便是COUNT(1)处理的逻辑过程.

再结合上SQL语句,假设按照下面的查询语句查询,

SELECT COUNT(1), CLASSID FROM Student
WHERE ID % 2 = 0;

首先是FROM Student WHERE ID % 2 = 0;获取到的结果如下:

IDNAMECLASSID
2xiaowang1
4xiaoming2
6xiaotian4
8xiaoqiang1
10xiaotie2
12wangwei3
14liqiang4

然后按照COUNT(1)处理后的结果如下:

IDNAMECLASSIDtmpCOUNT(1)
2xiaowang117
4xiaoming217
6xiaotian417
8xiaoqiang117
10xiaotie217
12wangwei317
14liqiang417

由于查询的数据只有CLASSID和COUNT(1)两列
故结果如下:

CLASSIDCOUNT(1)
17
27
47
17
27
37
47

在数据库上执行结果如下:
在这里插入图片描述

此时在结果上只展示了一条,这是为什么呢?我们接着往下看

GROUP BY + COUNT

在聚集函数一般与GROUP BY一起使用,如果没有使用GROUP BY,那么可以将当前表格中所有的数据看成一组(未分组就是一组),GROUP BY + SELECT只会保留每组中的第一条数据,上面实验中,由于有GROUP BY(没有使用GROUP BY相当于分组分成了一组)+ SELECT,故最终执行结果只有第一条数据

从之前的结果中我们知道,GROUP BY有按照某个属性分组,相同属性分为一组,如果在实验表中按照CLASSID分组,我们的结果如下:
CLASSID = 1 组:

IDNAMECLASSID
1xiaoming1
2xiaowang1
7xiaogang1
8xiaoqiang1

CLASSID=2组:

IDNAMECLASSID
3xiaotian2
4xiaoming2
9xiaojing2
10xiaotie2

CLASSID=3组:

IDNAMECLASSID
5xiaowang3
11wangqiang3
12wangwei3

CLASSID=4组:

IDNAMECLASSID
6xiaotian4
13liming4
14liqiang4

按照上面的规则,如果加上一个COUNT(1)属性,相当于在每个分组的后面加上了tmp列,然后COUNT(1)相当于在后面再加一列,该列的值为当前组的1的数量(如果没有分组就相当于整个表中tmp=1的数量),结果如下:

CLASSID = 1 组:

IDNAMECLASSIDtmpCOUNT(1)
1xiaoming114
2xiaowang114
7xiaogang114
8xiaoqiang114

CLASSID=2组:

IDNAMECLASSIDtmpCOUNT(1)
3xiaotian214
4xiaoming214
9xiaojing214
10xiaotie214

CLASSID=3组:

IDNAMECLASSIDtmpCOUNT(1)
5xiaowang313
11wangqiang313
12wangwei313

CLASSID=4组:

IDNAMECLASSIDtmpCOUNT(1)
6xiaotian413
13liming413
14liqiang413

如果执行下面的SQL语句

SELECT COUNT(1), NAME, CLASSID 
FROM Student
WHERE ID % 2 = 0
GROUP BY CLASSID;

则结果如下:
在这里插入图片描述
结果为上面四张表中每个表的第一行,取出COUNT(1),NAME, CLASSID的结果。

GROUP BY 后面还可以放多个属性,分组将按照这几个属性分,这几个属性相同的元素为一组,

GROUP_CONCAT

在聚集函数中,还有一个比较有意思的属性,GROUP_CONCAT,用于将同一个分组中每一行的几个属性拼接起来,通常和GROUP BY 一起使用。

如果不使用分组,那么表示当前表中所有的数据为一组,那么会在表中的每一列加上一个GROUP_CONCAT属性,行与行的拼接之间以逗号,分开,以下面的GROUP_CONCAT为例,该属性为拼接该表中所有的数据之后的结果如下:

GROUP_CONCAT(ID, '@', NAME, '@', CLASSID)

由于是聚合函数,同时也有分组,并且还和SELECT一起使用
以上面的SQL为例,加上GROUP_CONCAT函数之后的结果如下:

IDNAMECLASSIDGROUP_CONCAT(ID, ‘@’, NAME, ‘@’, CLASSID)
1xiaoming11@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
2xiaowang11@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
3xiaotian21@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
4xiaoming21@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
5xiaowang31@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
6xiaotian41@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
7xiaogang11@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
8xiaoqiang11@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
9xiaojing21@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
10xiaotie21@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
11wangqiang31@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
12wangwei31@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
13liming41@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4
14liqiang41@xiaoming@1,2@xiaowang@1,3@xiaotian@2,4@xiaoming@2,5@xiaowang@3,6@xiaotian@4,7@xiaogang@1,8@xiaoqiang@1,9@xiaojing@2,10@xiaotie@2,11@wangqiang@3,12@wangwei@3,13@liming@4,14@liqiang@4

假设执行下面的SQL语句

SELECT NAME, CLASSID, GROUP_CONCAT(ID, '@', NAME, '@', CLASSID)
FROM Student;

则结果如下:
在这里插入图片描述
如果加上GROUP BY,那么就是对每个组的属性进行拼接,以上面的SQL语句为例,

SELECT COUNT(1), NAME, CLASSID, GROUP_CONCAT(ID, '@', NAME, '@', CLASSID)
FROM Student
GROUP BY CLASSID;

则结果相当于从
CLASSID = 1 组:

IDNAMECLASSIDtmpCOUNT(1)GROUP_CONCAT(ID, ‘@’, NAME, ‘@’, CLASSID)
1xiaoming1141@xiaoming@1,2@xiaowang@1,7@xiaogang@1,8@xiaoqiang@1
2xiaowang1141@xiaoming@1,2@xiaowang@1,7@xiaogang@1,8@xiaoqiang@1
7xiaogang1141@xiaoming@1,2@xiaowang@1,7@xiaogang@1,8@xiaoqiang@1
8xiaoqiang1141@xiaoming@1,2@xiaowang@1,7@xiaogang@1,8@xiaoqiang@1

CLASSID=2组:

IDNAMECLASSIDtmpCOUNT(1)GROUP_CONCAT(ID, ‘@’, NAME, ‘@’, CLASSID)
3xiaotian2143@xiaotian@2,4@xiaoming@2,9@xiaojing@2,10@xiaotie@2
4xiaoming2143@xiaotian@2,4@xiaoming@2,9@xiaojing@2,10@xiaotie@2
9xiaojing2143@xiaotian@2,4@xiaoming@2,9@xiaojing@2,10@xiaotie@2
10xiaotie2143@xiaotian@2,4@xiaoming@2,9@xiaojing@2,10@xiaotie@2

CLASSID=3组:

IDNAMECLASSIDtmpCOUNT(1)GROUP_CONCAT(ID, ‘@’, NAME, ‘@’, CLASSID)
5xiaowang3135@xiaowang@3,11@wangqiang@3,12@wangwei@3
11wangqiang3135@xiaowang@3,11@wangqiang@3,12@wangwei@3
12wangwei3135@xiaowang@3,11@wangqiang@3,12@wangwei@3

CLASSID=4组:

IDNAMECLASSIDtmpCOUNT(1)GROUP_CONCAT(ID, ‘@’, NAME, ‘@’, CLASSID)
6xiaotian4136@xiaotian@4,13@liming@4,14@liqiang@4
13liming4136@xiaotian@4,13@liming@4,14@liqiang@4
14liqiang4136@xiaotian@4,13@liming@4,14@liqiang@4

最终通过SQL执行结果如下:
在这里插入图片描述

COUNT中可以放的值

COUNT中除了可以放* , 1, 等,还可以放属性,COUNT(NAME)的含义是计算同一个组中NAME中不为空的属性的属性,我们建立一个新的表

CREATE TABLE IF NOT EXISTS Teacher (
	ID INT PRIMARY KEY,
    NAME VARCHAR(20),
    CLASSID INT NOT NULL
);

INSERT INTO Teacher
VALUES 
(1, 'xiaoming', 1),
(2, 'xiaowang', 1),
(3, 'xiaotian', 2),
(4, NULL, 2),
(5, 'xiaowang', 3),
(6, 'xiaotian', 4),
(7, 'xiaogang', 1),
(8, 'xiaoqiang', 1),
(9, NULL, 2),
(10, 'xiaotie', 2),
(11, NULL, 3),
(12, NULL, 3),
(13, 'liming', 4),
(14, NULL, 4);

然后执行以下的SQL语句

SELECT COUNT(NAME), CLASSID
FROM Teacher
GROUP BY CLASSID;

执行 FROM Teacher GROUP BY CLASSID;

得到的结果是
CLASSID = 1 组:

IDNAMECLASSID
1xiaoming1
2xiaowang1
7xiaogang1
8xiaoqiang1

CLASSID=2组:

IDNAMECLASSID
3xiaotian2
4NULL2
9xiaojing2
10xiaotie2

CLASSID=3组:

IDNAMECLASSID
5xiaowang3
11NULL3
12NULL3

CLASSID=4组:

IDNAMECLASSID
6xiaotian4
13liming4
14NULL4

那么,在执行COUNT(NAME)后,会在上述表的后面加上一列
CLASSID = 1 组:

IDNAMECLASSIDCOUNT(NAME)
1xiaoming14
2xiaowang14
7xiaogang14
8xiaoqiang14

CLASSID=2组:

IDNAMECLASSIDCOUNT(NAME)
3xiaotian22
4NULL22
9NULL22
10xiaotie22

CLASSID=3组:

IDNAMECLASSIDCOUNT(NAME)
5xiaowang31
11NULL31
12NULL31

CLASSID=4组:

IDNAMECLASSIDCOUNT(NAME)
6xiaotian42
13liming42
14NULL42

最终执行完SQL之后的结果如下:
在这里插入图片描述
此外,COUNT在添加属性的时候,还可以加上DISTINCT属性,以达到去重的目标
实验时,将ID=2的NAME属性更新为NAME=1的属性,然后观察CLASSID=1的组中的NAME属性去重后的COUNT.

SELECT COUNT(DISTINCT NAME), CLASSID 
FROM Teacher
WHERE CLASSID=1;

最终通过执行SQL得到的结果为3,因为ID=1和ID=2的NAME属性重复了。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值