MySQL数据库(六)

目录

一、表的设计

1.1 一对一

1.2 一对多 

1.3 多对多

1.4设计表与插入数据 

1.5表中数据拷贝

二、复杂查询

2.1 聚合查询

2.1.1聚合函数

2.1.2 group by子句

2.1.3 having


一、表的设计

三大范式:

1.1 一对一

1.2 一对多 

1.3 多对多

1.4设计表与插入数据 

  • 创建班级表

create table classes(
         id int primary key auto_increment,
         name varchar(20),
         `desc` varchar(100)
);

  • 创建学生表

 create table student(
         id int primary key auto_increment,
         sn varchar(20),
         name varchar(20),
         email varchar(20),
         classes_id int
);

  • 创建课程表

-- 创建课程表
create table course(
         id int primary key auto_increment,
         name varchar(20)
);

  • 创建课程学生中间表:考试成绩表

create table score(
         score decimal(3,1),
         student_id int,
         course_id int,
         foreign key (student_id) references student (id),
         foreign key (course_id) references course (id)
);

  • 对班级表插入数据

insert into classes(name, `desc`) values
         ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
         ('中文系2019级3班','学习了中国传统文学'),
         ('自动化2019级5班','学习了机械自动化');

  •  学生表插入数据

insert into student(sn, name, email, classes_id) values
         ('09982','黑旋风李逵','[email protected]',1),
         ('00835','菩提老祖',null,1),
         ('00391','白素贞',null,1),
         ('00031','许仙','[email protected]',1),
         ('00054','不想毕业',null,1),
         ('51234','好好说话','[email protected]',2),
         ('83223','tellme',null,2),
         ('09527','老外学中文','[email protected]',2);

  •  对课程表插入数据

insert into course(name) values

        ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

  •  成绩表插入数据

insert into score(score, student_id, course_id) values
         -- 黑旋风李逵
         (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
         -- 菩提老祖
         (60, 2, 1),(59.5, 2, 5),
         -- 白素贞
         (33, 3, 1),(68, 3, 3),(99, 3, 5),
         -- 许仙
         (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
         -- 不想毕业
         (81, 5, 1),(37, 5, 5),
         -- 好好说话
         (56, 6, 2),(43, 6, 4),(79, 6, 6),
         -- tellme
         (80, 7, 2),(92, 7, 6);

 

1.5表中数据拷贝

语法:

insert into table_name(列名1,列名2) select ....

案例:创建一张用户表,设计有name姓名、email邮箱、sex性别、mobile手机号字段。需要把已有的学生数据复制进来,可以复制的字段为name、qq_mail

create table test_user (
        id int primary key auto_increment,
        name varchar(20) comment '姓名',
        age int comment '年龄',
        email varchar(20) comment '邮箱',
        sex varchar(1) comment '性别',
        mobile varchar(20) comment '手机号'
);

-- 将学生表中的所有数据复制到用户表

insert into test_user(name, email) select name, qq_mail from student;

二、复杂查询

前面介绍过数据库的基本查询也就是单表数据查询,这里要介绍的是数据库中的多表查询

2.1 聚合查询

2.1.1聚合函数

常见的统计总数、计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有:

函数 说明
count([distinct] expr) 返回查询到的数据的 数量
sum([distinct] expr) 返回查询到的数据的 总和,不是数字没有意义
avg([distinct] expr) 返回查询到的数据的 平均值,不是数字没有意义
max([distinct] expr) 返回查询到的数据的 最大值,不是数字没有意义
min([distinct] expr) 返回查询到的数据的 最小值,不是数字没有意义

案例:

  • count 对数据行进行统计

--统计班级共有多少同学
select count(*) from student; --统计有多少行数据
select count(0) from student; --统计主键列有多少行数据

-- 统计班级收集的 email 有多少个,email 为 null的数据不会计入结果

 select count(email) from student;

通过这个统计我们发现当数据为空的时候是不会进行统计的

  • sum 计算数据列的数据总和(只能针对数字)

 -- 统计数学成绩总分

select sum(math) from exam_result;

 -- 不及格 < 60 的总分,没有结果,返回 NULL

select sum(math) from exam_result where math < 60;

  • avg 对数据列的数据进行求平均(只针对数字)

-- 统计平均总分

select avg(english + chinese + math) from exam_result ;

  • max 针对某列数据取最大值(只针对数字)

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

  • min针对某列数据取最小值(只针对数字)

-- 返回 > 70 分以上的数学最低分

select min(math) from exam_result where math > 70;

2.1.2 group by子句

select 中使用 group by 子句可以对指定列进行分组查询。需要满足:使用 group by 进行分组查询时,select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中。

案例:准备测试表:职员表,有id(主键)、name(姓名)、role(角色)、salary(薪水)

create table emp(
        id int primary key auto_increment,
        name varchar(20) not null,
        role varchar(20) not null,
        salary numeric(11,2)
);


insert into emp(name, role, salary) values
        ('马云','服务员', 1000.20),
        ('马化腾','游戏陪玩', 2000.99),
        ('孙悟空','游戏角色', 999.11),
        ('猪无能','游戏角色', 333.5),
        ('沙和尚','游戏角色', 700.33),
        ('隔壁老王','董事长', 12000.66);

--查询每个角色的最高工资、最低工资和平均工资

 select role,max(salary),min(salary),avg(salary)
 from emp group by role;

 2.1.3 having

group by 子句进行分组以后,需要对分组结果再进行条件过滤时不能使用 where 语句,而需要用 having但是一个语句中也可以同时含有wherehaving

--显示平均工资低于1500的角色和它的平均工资
select role,avg(salary) from emp group by role
having avg(salary) < 1500;

--显示除掉董事长并且平均工资高于1500的角色与平均工资

select role, avg(salary) from emp where role !='董事长'
group by role having avg(salary) > 1500;

猜你喜欢

转载自blog.csdn.net/x2656271356/article/details/131818760