MySQL表的增删改查(进阶)

MySQL表的增删改查(进阶)

数据库约束

约束类型

NOT NULL - 指示某列不能存储 NULL 值。(如果尝试往这里插入空值,就会直接报错)
    -- 示例 --
  -- 重新设置学生表结构
    drop table if exists student;
    create table student (id int not null, sn int, name varchar(20), qq_mail varchar(20));   

在这里插入图片描述

UNIQUE - 保证某列的每行必须有唯一的值。(如果尝试往这里插入重复的值,就会直接报错)
-- 重新设置学生表结构
drop table if exists student;
create table student (id int not null, sn int unique, name varchar(20), qq_mail varchar(20));

在这里插入图片描述

DEFAULT - 规定没有给列赋值时的默认值。(默认的默认值为NULL)
-- 重新设置学生表结构
drop table if exists student;
create table student (id int not null, sn int unique, name varchar(20) default '匿名', qq_mail varchar(20));

在这里插入图片描述

PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
(主键约束,相当于数据的唯一身份标识,类似于身份证号码/手机号码)
drop table if exists student;
create table student (id int primary key, sn int unique, name varchar(20) default '匿名', qq_mail varchar(20));

对于整数类型的主键,常配搭自增长auto_increment来使用。插入数据对应字段不给值时,使用最大值+1。

-- 主键是 NOT NULL 和 UNIQUE 的结合,可以不用 NOT NULL
id int primary key auto_increment,

自增主键也是可以手动指定id的,一旦指定过后就是从指定后的数往后开始自增了.

在这里插入图片描述

在这里插入图片描述

FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
(外键约束: 描述两个表之间的关联关系,1的数据必须在表2中存在)
-- FOREIGN KEY:外键约束,外键用于关联其他表的主键或唯一键,语法:
foreign key (字段名) references 主表()
-- 创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识
drop table if exists class;
create table class(classId int primary key auto_increment, name varchar(20));
insert into class values (null, 'java100');
insert into class values (null, 'java101');
insert into class values (null, 'java102');
select * from class;

在这里插入图片描述

创建学生表student,一个学生对应一个班级,一个班级对应多个学生。使用id为主键,classId为外键,关联班级表id
drop table if exists student;
create table student(studentId int primary key auto_increment, name varchar(20),
classId int, foreign key (classId) references class(classId));
insert into student values (null, '张三', 1);
insert into student values (null, '张三', 100);

在这里插入图片描述

不仅插入受到外键约束,插入成功的子表修改也受到外键的约束,

外键约束同样约束父表.一旦子表依赖着父表那这条父表记录也不可修改删除(相互约束)

CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句。
(指定一个条件,通过条件来对值进行判定.但是MySQL并不支持)

表的设计

一对一

在这里插入图片描述

一对多
在这里插入图片描述

在这里插入图片描述

多对多

在这里插入图片描述
在这里插入图片描述

新增

插入查询结果

drop table A;
drop table B;
create table A (id int, name varchar(20));
insert into A values (1, '张三');
insert into A values (2, '王五');
create table B (id int, name varchar(20));
--A的数据插入到B--
insert into B select * from A;

在这里插入图片描述

查询

聚合查询

聚合函数

在这里插入图片描述

-- 统计班级共有多少同学
select count(*) from exam_result;

在这里插入图片描述

count 函数对 NULL 不会纳入统计

-- 统计班级同学语文总分
select sum(chinese) from exam_result;

在这里插入图片描述

sum **这个操作只能针对数字进行运算,不能针对字符串来进行**

GROUP BY子句

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

-- 语法 --
select column1, sum(column2), .. from table group by column1,column3;
-- 案例 --
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 * from emp;
select role, max(salary), min(salary), avg(salary) from emp group by role;

在这里插入图片描述

HAVING

group by 是可以使用where 只不过where是在分组之前执行的,如果要对分组之后的结果进行条件筛选,就需要使用 having.

在这里插入图片描述

联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:(笔试爱考,但是实际工作中一般禁止使用多表查询)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

完整代码:

drop database if exists java20220517;
create databases java20220517;
use java20220517;
drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;
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(100), qq_mail 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);
insert into classes(name, `desc`) values
('计算机系20191', '学习了计算机原理,CJava语言,数据结构和算法'),
('中文系20193','学习了中国传统文学'),
('自动化20195','学习了机械自动化');
insert into student(sn, name, qq_mail, classes_id) values
('09982', '黑旋风李逵', 'xuanfeng@qq.com', 1),
('00835', '菩提老祖', null, 1),
('00391', '白素贞', null, 1),
('00031', '许仙', 'xuxian@qq.com', 1),
('00054', '不想毕业', null, 1),
('51234', '好好说话', 'say@qq.com', 2),
('83223', 'tellme', null, 2),
('09527', '老外学中文', 'foreigner@qq.com', 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: 查询许仙同学的成绩

分析: 许仙选了许多课,就需要在学生表里获取学生的姓名,在分数表里获取分数信息

在这里插入图片描述

在这里插入图片描述

问题2: 查询所有同学的总成绩,及同学的个人信息:

这个案例要在多表查询的基础上,再加上一个聚合查询(group by)

在这里插入图片描述

问题3查询所有同学的成绩,及同学的个人信息:

这里不光要查询同学的名字,还有课程的名字,以及分数.这个时候就涉及到三张表的联合查询(同学名字 => 学生表, 课堂名字 => 课程表, 分数 => 分数表)三张表,两张表的笛卡尔积规则是一样的

在这里插入图片描述

在这里插入图片描述

外连接

语法: from 表1 join 表2 on 条件 join 表3 on 条件;

select 列名 from 表1 inner (可以省略) join 表2 on 条件(内连接)

select 列名 from 表1 left join 表2 on 条件(左外连接)

select 列名 from 表1 right join 表2 on 条件(右外连接)

在这里插入图片描述

自连接

自连接是指在同一张表连接自身进行查询。(自连接就是把行转换为列,再来查询)
案例:
显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

在这里插入图片描述

子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询(把多个select合并为一个)

单行子查询:返回一行记录的子查询
问题:查询与“不想毕业” 同学的同班同学:

在这里插入图片描述

多行子查询:返回多行记录的子查询
案例:查询“语文”或“英文”课程的成绩信息

在这里插入图片描述

NOT] EXISTS关键字:

-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou
where (name='语文' or name='英文') and cou.id = sco.course_id);
-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou
where (name!='语文' and name!='英文') and cou.id = sco.course_id);

合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致。

union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。(union不同的两张表也可以合并查询,而 or 是必须是同一张表中来查询)
案例:查询id小于3,或者名字为“英文”的课程:

select * from course where id<3 union select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';

在这里插入图片描述

union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
案例:查询id小于3,或者名字为“Java”的课程

-- 可以看到结果集中出现重复数据Java
select * from course where id<3 union all select * from course where name='英文';

总结

1.数据库约束
null 约束 (使用NOT NULL指定列不为空) name varchar(20) not null,

unique 唯一约束(指定列为唯一的、不重复) name varchar(20) unique,

default 默认值约束(指定列为空时的默认值) age int default 20,

primary key主键约束 (NOT NULL 和 UNIQUE 的结合) id int primary key,

foreign key外键约束(关联其他表的主键或唯一键)foreign key (字段名) references 主表()

check 约束(保证列中的值符合指定的条件)check (sex ='男' or sex='女')

2.表的关系
	1. 一对一:
	2. 一对多:
	3. 多对多:需要创建中间表来映射两张表的关系
    
3.新增:
	insert into table_name [(column [, column ...])] select ...

4.查询
	1. 聚合函数:MAX、MIN、AVG、COUNT、SUM
	2. 分组查询:GROUP BY... HAVING ...
	3. 内连接:
	select ... from 表1,表2 where 条件
	-- inner可以缺省
	select ... from 表1 join 表2 on 条件 where 其他条件
4. 外连接:
	select ... from 表1 left/right join 表2 on 条件 where 其他条件
5. 自连接:
	select ... from 表1,表1 where 条件
	select ... from 表1 join 表1 on 条件
6. 子查询:
	-- 单行子查询
	select ... from 表1 where 字段1 = (select ... from ...);
	-- [NOT] IN
	select ... from 表1 where 字段1 in (select ... from ...);
	-- [NOT] EXISTS
	select ... from 表1 where exists (select ... from ... where 条件);
	-- 临时表:form子句中的子查询
	select ... from 表1(select ... from ...) as tmp where 条件
7. 合并查询:
	-- UNION:去除重复数据
	select ... from ... where 条件
	union
	select ... from ... where 条件
	-- UNION ALL:不去重
	select ... from ... where 条件
	union all
	select ... from ... where 条件
	-- 使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

SQL查询中各个关键字的执行先后顺序: from > on> join > where > group by > with > having >select > distinct > order by > limit

猜你喜欢

转载自blog.csdn.net/TuttuYYDS/article/details/124919017