【MySql】聚合函数&&group by&&OJ题目


本篇主要介绍mysql的聚合函数和group by的使用,最后是OJ题目的练习。

聚合函数

MySQL中的聚合函数用于对数据进行计算和统计,常见的聚合函数包括下面列举出来的聚合函数:

		函数									说明
COUNT([DISTINCT] expr) 				返回查询到的数据的数量
SUM([DISTINCT] expr) 				返回查询到的数据的总和,不是数字没有意义
AVG([DISTINCT] expr) 				返回查询到的数据的平均值,不是数字没有意义
MAX([DISTINCT] expr) 				返回查询到的数据的最大值,不是数字没有意义
MIN([DISTINCT] expr) 				返回查询到的数据的最小值,不是数字没有意义

对于上面所列举出来的聚合函数,下面我们通过一些案例来进行对聚合函数的运用,增强理解,话不多说

  • 统计班级共有多少同学
-- 使用 * 做统计,不受 NULL 影响
select count(*) from exam_result;

-- 使用表达式做统计
select count(1) from exam_result;

image-20230614190926674

image-20230614191010459

  • 统计班级的数学成绩有多少个
select count(math) from exam_result;

image-20230614191208856

但是我们看到了数学成绩是有重复的,如何去重?distinct

select distinct count(distinct math) from exam_result;

image-20230614191642323

  • 统计数学成绩总分
select sum(math) from exam_result;

image-20230614191755416

  • 统计数学成绩的平均分
select sum(math)/count(*) from exam_result;

select avg(math) from exam_result;

image-20230614192404128

  • 统计英语成绩不及格的人数
 select count(*) from exam_result where english<60;

image-20230614192613880

  • 返回英语最高分
select max(english) from exam_result;

image-20230614192902514

  • 返回 > 70 分以上的数学最低分
select min(math) from exam_result where math>70;

image-20230614193443797

分组group by使用

分组的目的是为了进行分组之后,方便进行聚合统计

在select中使用group by 子句可以对指定列进行分组查询

select column1, column2, .. from table group by column;

先创建一个雇员信息表
EMP员工表
DEPT部门表
SALGRADE工资等级表
如何显示每个部门的平均工资和最高工资

image-20230615000430588

image-20230615000854934

  • 显示每个部门的平均工资和最高工资
select deptno,max(sal) 最高,avg(sal) 平均 from emp group by deptno;

image-20230615075542834

分组就是把一组按照条件拆分成多个组,进行各自组内的统计分组;就是把一张表按照条件在逻辑上拆成了多个子表,然后分别对各自的子表进行聚合统计。

  • 显示每个部门的每种岗位的平均工资和最低工资
select deptno,job, avg(sal) 平均,min(sal) 最低 from emp group by deptno,job;

image-20230615084036318

  • 显示平均工资低于2000的部门和它的平均工资

统计各个部门的平均工资

select avg(sal) from EMP group by deptno

having和group by配合使用,对group by结果进行过滤

select avg(sal) as myavg from EMP group by deptno having myavg<2000;

having就是对聚合后的统计数据,条件筛选

  • having和where区别理解,执行顺序

image-20230615093211253

条件筛选的阶段是不同的。不要单纯的认为只有在磁盘上表结构导入到mysql,真实存在的表才叫做表,中间筛选出来的包括最终结果全部都是逻辑上的表,可以理解为mysql一切皆为表。未来只要我们能够处理好单标的CURD,所有的sql场景我们全部都能用统一的方式进行。

学习完上面的知识之后,我们下面进行一些OJ题目练习,题目来源牛客网与leetcode,做一做,提高自己编写sql的能力

OJ题目

SQL228 批量插入数据

描述

题目已经先执行了如下语句:

drop table if exists actor;
CREATE TABLE actor (
actor_id  smallint(5)  NOT NULL PRIMARY KEY,
first_name  varchar(45) NOT NULL,
last_name  varchar(45) NOT NULL,
last_update  DATETIME NOT NULL)

请你对于表actor批量插入如下数据(不能有2条insert语句哦!)

actor_id first_name last_name last_update
1 PENELOPE GUINESS 2006-02-15 12:34:33
2 NICK WAHLBERG 2006-02-15 12:34:33

sql语句如下:

insert into actor (actor_id,first_name,last_name,last_update) values (1,'PENELOPE','GUINESS','2006-02-15 12:34:33'),(2,'NICK','WAHLBERG','2006-02-15 12:34:33');

SQL202 找出所有员工当前薪水salary情况

描述

有一个薪水表,salaries简况如下:

emp_no salary from_date to_date
10001 72527 2002-06-22 9999-01-01
10002 72527 2001-08-02 9999-01-01
10003 43311 2001-12-01 9999-01-01

请你找出所有员工具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示,以上例子输出如下:

salary
72527
43311

sql语句如下:

select  distinct salary from salaries order by salary desc;

SQL195 查找最晚入职员工的所有信息

描述

有一个员工employees表简况如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1985-11-21
10003 1959-12-03 Parto Bamford M 1986-08-28
10004 1954-05-01 Christian Koblick M 1986-12-01

请你查找employees里最晚入职员工的所有信息,以上例子输出如下:

emp_no birth_date first_name last_name gender hire_date
10004 1954-05-01 Christian Koblick M 1986-12-01
select * from employees order by hire_date desc limit 1;

SQL196 查找入职员工时间排名倒数第三的员工所有信息

描述

有一个员工employees表简况如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26
10002 1964-06-02 Bezalel Simmel F 1985-11-21
10003 1959-12-03 Parto Bamford M 1986-08-28
10004 1954-05-01 Christian Koblick M 1986-12-01

请你查找employees里入职员工时间排名倒数第三的员工所有信息,以上例子输出如下:

emp_no birth_date first_name last_name gender hire_date
10001 1953-09-02 Georgi Facello M 1986-06-26

注意:可能会存在同一个日期入职的员工,所以入职员工时间排名倒数第三的员工可能不止一个。

select * from employees 
where hire_date=(select distinct hire_date from employees order by hire_date desc limit 2,1);

SQL201 查找薪水记录超过15条的员工号emp_no以及其对应的记录次数t

select emp_no,count(*) as t from salaries group by emp_no having t>15;

从titles表获取按照title进行分组

select title,count(title) as t from titles
group by title having t>=2;

182. 查找重复的电子邮箱

select email from Person group by email having count(email)>1;

595. 大的国家

select name,population,area from world
where area >= 3000000 or population >= 25000000;

猜你喜欢

转载自blog.csdn.net/weixin_60478154/article/details/131247690