Mysql表增删查改进阶

Mysql增删查改进阶

  • 一.数据库约束关系
    • 1.not null
    • 2.unique
    • 3.default
    • 4.primary key
    • 5.foreign key
    • 6.check
  • 二.新增
  • 三.查询
    • 1.聚合查询
      • 1.1.常见的聚合函数
        • count
        • sum
        • avg
        • max
        • min
      • 1.2.分组查询
    • 2.联合查询(连接查询)
      • 2.1内连接
      • 2.2外连接
        • 左连接
        • 右连接
      • 2.3自连接
      • 2.4子查询
        • 2.4.1:单行子查询
        • 2.4.2:多行子查询
          • in和not in
          • exists 和 not exists
      • 2.5合并查询
        • union
        • union all

一.数据库约束关系

约束类型 作用
not null 某列不能存储null值
unique 某列的值唯一,该列每一行必须不同
default 没有给列赋值时的默认值
primary key 主键,唯一标识某列(或者多列的结合),便于快速找到表中的一条特定的记录.
该约束是not null 和unique的结合
foreign key 外键,保证一张表中的数据匹配到另一张表中的值
check 保证列中的值符合指定的条件。
对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句

1.not null

创建表时,保证某列不为空

示例:

drop table if exists student;
create table if not exists student
(
	id int not null,
	name varchar(20)
);

2.unique

唯一键,指定某列是唯一的、不重复的
当某列同时设置约束为not null和unique时,会将这一列自动升级为主键
示例:

drop table if exists student;
create table if not exists student
(
	id int not null unique,
	name varchar(20)
);

表结构:
Mysql表增删查改进阶_第1张图片

3.default

设置某列的默认值
示例:

drop table if exists student;
create table if not exists student(
	id int not null unique,
	name varchar(20) default "神秘人"
);

表结构:
Mysql表增删查改进阶_第2张图片

4.primary key

主键约束,指定某列或某几列为主键
当主键为整数类型时,常搭配auto_increment(自增长约束)使用
示例:

drop table if exists student;
create table if not exists student(
	id int primary key auto_increment,
	name varchar(20) default "神秘人"
);

表结构:
Mysql表增删查改进阶_第3张图片

5.foreign key

外键约束,外键用来关联其他表的主键或者唯一键
建立外键约束,需要保证要关联的表是已经存在的,也就是说需要先创建被关联的表,才能建立外键约束

语法:

foreign key (本表字段) references 主表A(字段a);
# 将本表字段设置为主表A的外键,和主表A的字段a相关联

使用示例:

drop table if exists class;
create table if not exists class(
	id int primary key auto_increment,
	name varchar(20)
);

drop table if exists student;
create table if not exists student(
	id int primary key auto_increment,
	name varchar(20) default "神秘人",
	class_id int,
	foreign key (class_id) references class(id)
);

表结构:
Mysql表增删查改进阶_第4张图片

6.check

保证列中的值符合指定的条件,mysql在使用是不会报错,但是mysql会忽略该约束
示例:

# 建表
drop table if exists worker;
create table if not exists worker(
	id int primary key auto_increment, 
	sex varchar(10),
	check (sex = "男" or sex = "女")
);

# 插入测试数据
insert into worker values(null, "男");
insert into worker values(null, "女");
insert into worker values(null, "未知");

# 查看表数据
select * from worker;

查询结果:
Mysql表增删查改进阶_第5张图片

二.新增

将一张表中的查询结果插入另一张表
语法:

insert into1(字段1, 字段2, ...) select ...

示例:

drop table if exists student;
create table if not exists student(
	name varchar(20),
	age int
);

drop table if exists people;
create table if not exists people(
	name varchar(20),
	age int
);

insert into student values
("遇见是场意外", 22),
("小公主", 10),
("程序员天花板", 45);

insert into people(name, age) select name, age from student;
 
select * from people;

查询结果:
Mysql表增删查改进阶_第6张图片

三.查询

1.聚合查询

1.1.常见的聚合函数

Mysql提供了一些常见的函数用于进行查询,常见的如下:

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

聚合函数查询使用的表:

drop table if exists score;
create table if not exists score(
name varchar(20),
score int);

insert into score values
("语文", 100),
("数学", 99),
("英语", 88),
("C++", 99),
("Linux", 99);

count

统计字段出现的个数
示例:

select count(name) from score;

查询结果:
Mysql表增删查改进阶_第7张图片

sum

计算字段的总和

示例:

select sum(score) from score;

查询结果:
Mysql表增删查改进阶_第8张图片

avg

计算字段的平均值
示例:

select avg(score) from score;

查询结果:
Mysql表增删查改进阶_第9张图片

max

计算查询字段中的最大值

示例:

select max(score) from score;

查询结果:
Mysql表增删查改进阶_第10张图片

min

计算字段的最小值
示例:

select min(score) from score;

查询结果:
Mysql表增删查改进阶_第11张图片

1.2.分组查询

使用group by子句可以将查询结果按照属性列或者属性列组合在行的方向上分组,每组具有相同的值
group by进行分组后,如果要进行条件过滤必须使用having,而不能使用where

分组查询的表和测试数据:

drop table if exists worker;
create table if not exists worker(
	id int primary key auto_increment, 
	name varchar(20) not null,
 	profession varchar(20) not null comment "职业",
 	salary decimal(10, 2)
);

insert into worker(name, profession, salary) values 
	("孙悟空", "高级保镖", 10000),
	("猪八戒", "高级保镖", 8000),
	("沙和尚", "高级保镖", 8000),
	("白龙马", "坐骑", 4000),
	("唐三藏", "主管", 30000),
	("二郎神", "总经理", 70000),
	("如来", "董事长", 1000000);

示例1:

select profession, max(salary), avg(salary) from worker
group by profession;

查询结果:
Mysql表增删查改进阶_第12张图片
示例2:

select profession, max(salary), avg(salary) from worker 
group by profession having avg(salary) < 10000;

查询结果:
Mysql表增删查改进阶_第13张图片

2.联合查询(连接查询)

数据库的各个表中存放着不同的数据,用户往往需要多个表中的数据来组联合起来进行查询,如果一个查询需要使用多个表,就称为连接查询。
连接查询分为两步,第一步是将各个表连接起来取笛卡尔积,第二步是根据条件进行筛选。

联合查询测试数据:

# 班级表
drop table if exists classes;
create table if not exists classes(
	id int primary key auto_increment,
	name varchar(20) not null
);

# 学生表
drop table if exists student;
create table if not exists student(
	id int primary key auto_increment,
	name varchar(20) not null,
	sn int unique not null comment "学号",
	email varchar(20) not null,
	class_id int not null comment "班级号",
	foreign key (class_id) references classes(id)
);

#课程表
drop table if exists course;
create table if not exists course(
	id int primary key auto_increment,
	name varchar(20) not null
);

#分数表
drop table if exists score;
create table if not exists score(
	id int primary key auto_increment,
	points decimal(5.1) not null comment "分数",
	student_id int not null comment "学号",
	course_id int not null comment "课程号",
	foreign key (student_id) references student(id),
	foreign key (course_id ) references course(id)
); 

#测试数据
insert into classes values 
(null, "乘风破浪的少年"), 
(null, "孤勇者"), 
(null, "元气少女1024");

insert into course values 
(null, "c++"), 
(null, "linux"), 
(null, "网络");

insert into student values
(null, "迪奥", 1001, "123@qq.com", 1),
(null, "承太郎", 1002, "245@qq.com", 1),
(null, "路飞", 1003, "666@qq.com", 1),
(null, "索隆", 1004, "899@163.com", 2),
(null, "山治", 1005, "888@163.com", 2),
(null, "娜美", 1006, "789@163.com", 2),
(null, "罗宾", 1007, "8899@163.com", 3),
(null, "乌索普", 1008, "12345@163.com", 3);

insert into score values
(null, 99, 1, 1),
(null, 98, 1, 2),
(null, 100, 1, 3),
(null, 100, 2, 1),
(null, 60, 3, 2),
(null, 60, 3, 3),
(null, 90, 7, 2),
(null, 77, 4, 1),
(null, 34, 5, 3);

2.1内连接

根据两个表中的记录,返回关联字段相符的记录。也就是求两个表的公共部分(交集)
语法:

# 形式1 
# inner可以省略,不加inner默认为内连接
select 字段 from1 别名1 inner join2 别名2 on 连接条件 and 其他条件;
# 形式2
select 字段 from1 别名1,2 别名2 where 连接条件 and 其它条件;

示意图:
Mysql表增删查改进阶_第14张图片

示例1:
查询迪奥的成绩
查询语句:

# 形式2
select stu.name, sco.points from score sco, student stu
where stu.id = sco.student_id and stu.name = "迪奥";

# 形式1
select stu.name, sco.points from score sco
join student stu 
on stu.id = sco.student_id
and stu.name = "迪奥";

查询结果:
Mysql表增删查改进阶_第15张图片
示例2:
查询有成绩的同学的个人信息和课程成绩
查询语句:

select stu.*, cou.name, sco.points from student stu
join score sco
on stu.id = sco.student_id
join course cou
on cou.id = sco.course_id;

查询结果:
Mysql表增删查改进阶_第16张图片

2.2外连接

使用主表的每行数据去匹配从表的数据列,符合连接条件的数据将直接返回到结果集中,对不符合连接条件的列,也就是从表的列将被填上null值后,再返回到结果集中。

外连接分为左外连接和右外连接两种
根据主表所在的方向区分外连接,主表在左边,则称为左连接,主表在右边,则称为右连接;

左连接

用左边的表作为主表和右边的表进行匹配,如果右边不符合条件,为右表的列填上null值
关键词:left join

示例:

select stu.*, cou.name, sco.points from student stu
left join score sco
on stu.id = sco.student_id
left join course cou
on cou.id = sco.course_id;

查询结果:
Mysql表增删查改进阶_第17张图片

右连接

用右边的表作为主表和左边的表进行匹配,如果左边不符合条件,为左表的列填上null值

关键词:right join

示例:

select stu.*, cou.name, sco.points from student stu
right join score sco
on stu.id = sco.student_id
right join course cou
on cou.id = sco.course_id;

查询结果:
Mysql表增删查改进阶_第18张图片

2.3自连接

同一张表和自身进行连接查询
适用于对同一张表中的某些字段进行比较的查询操作

示例:
查询c++成绩比网络成绩低的学生信息

select stu.*, s1.points "c++", s2.points"网络"
from score s1
join score s2 on s1.student_id = s2.student_id
join student stu on stu.id = s1.student_id
join course c1 on s1.course_id = c1.id
join course c2 on s2.course_id = c2.id
and c1.name = "c++"
and c2.name = "网络"
and s1.points < s2.points;

查询结果:
Mysql表增删查改进阶_第19张图片

2.4子查询

在where子句中包含一个形如select-from-where的查询块,这种查询语句称之为子查询,
也就是将一个查询结果的输出作为另一个查询结果的输入。

2.4.1:单行子查询

返回一行记录的子查询

示例:
查询和路飞同班级的同学信息

select * from student where class_id =  
(select class_id from student where name = "路飞");

查询结果:
Mysql表增删查改进阶_第20张图片

2.4.2:多行子查询

返回多行记录的子查询

两种形式的查询语句:

in和not in

in表示字段在这个集合中,not in表示不在集合中

示例1:
查询c++课程和linux课程的成绩信息

select * from score where course_id 
in (select id from course where name = "c++" 
or name = "linux");

查询结果:
Mysql表增删查改进阶_第21张图片
示例2:
查询课程不是c++课程和linux课程的成绩信息

select * from score where course_id 
not in (select id from course where name = "c++" or name = "linux");

查询结果:
Mysql表增删查改进阶_第22张图片

exists 和 not exists

将查询语句的每一行数据拿出来和exists或者not exists的条件进行比对,如果满足条件就加入结果集

示例1:
查询c++课程和linux课程的成绩信息

select * from score sco 
where exists(
select cou.id from course cou 
where (cou.name = "c++" or cou.name = "linux") 
and sco.course_id = cou.id);

查询结果:
Mysql表增删查改进阶_第23张图片
示例2:
查询课程不是c++和linux的成绩信息

select * from score sco where not exists  
(select sco.id from course cou  
where (name="c++" or name="linux")  
and cou.id = sco.course_id);

查询结果:
Mysql表增删查改进阶_第24张图片

2.5合并查询

合并多个查询的执行结果,使用集合操作符union和union all,但是前后查询的结果集中,字段需要一致

union

取两个结果集的并集,当结果集中有重复行时,会自动去重

示例:
查询id != 2 或者 名字为c++的课程

select * from course where id != 2
union
select * from course where name = "c++"; 

查询结果:
Mysql表增删查改进阶_第25张图片

union all

取两个结果集的并集,当结果集中有重复行时,不会去重

示例:
查询id != 2 或者 名字为c++的课程

select * from course where id != 2
union all
select * from course where name = "c++"; 

查询结果:
Mysql表增删查改进阶_第26张图片

你可能感兴趣的