约束类型 | 作用 |
---|---|
not null | 某列不能存储null值 |
unique | 某列的值唯一,该列每一行必须不同 |
default | 没有给列赋值时的默认值 |
primary key | 主键,唯一标识某列(或者多列的结合),便于快速找到表中的一条特定的记录. 该约束是not null 和unique的结合 |
foreign key | 外键,保证一张表中的数据匹配到另一张表中的值 |
check | 保证列中的值符合指定的条件。 对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句 |
创建表时,保证某列不为空
示例:
drop table if exists student;
create table if not exists student
(
id int not null,
name varchar(20)
);
唯一键,指定某列是唯一的、不重复的
当某列同时设置约束为not null和unique时,会将这一列自动升级为主键
示例:
drop table if exists student;
create table if not exists student
(
id int not null unique,
name varchar(20)
);
设置某列的默认值
示例:
drop table if exists student;
create table if not exists student(
id int not null unique,
name varchar(20) default "神秘人"
);
主键约束,指定某列或某几列为主键
当主键为整数类型时,常搭配auto_increment(自增长约束)使用
示例:
drop table if exists student;
create table if not exists student(
id int primary key auto_increment,
name varchar(20) default "神秘人"
);
外键约束,外键用来关联其他表的主键或者唯一键
建立外键约束,需要保证要关联的表是已经存在的,也就是说需要先创建被关联的表,才能建立外键约束
语法:
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在使用是不会报错,但是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;
将一张表中的查询结果插入另一张表
语法:
insert into 表1(字段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提供了一些常见的函数用于进行查询,常见的如下:
函数 | 说明 |
---|---|
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);
统计字段出现的个数
示例:
select count(name) from score;
计算字段的总和
示例:
select sum(score) from score;
计算字段的平均值
示例:
select avg(score) from score;
计算查询字段中的最大值
示例:
select max(score) from score;
计算字段的最小值
示例:
select min(score) from score;
使用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;
select profession, max(salary), avg(salary) from worker
group by profession having avg(salary) < 10000;
数据库的各个表中存放着不同的数据,用户往往需要多个表中的数据来组联合起来进行查询,如果一个查询需要使用多个表,就称为连接查询。
连接查询分为两步,第一步是将各个表连接起来取笛卡尔积,第二步是根据条件进行筛选。
联合查询测试数据:
# 班级表
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, "[email protected]", 1),
(null, "承太郎", 1002, "[email protected]", 1),
(null, "路飞", 1003, "[email protected]", 1),
(null, "索隆", 1004, "[email protected]", 2),
(null, "山治", 1005, "[email protected]", 2),
(null, "娜美", 1006, "[email protected]", 2),
(null, "罗宾", 1007, "[email protected]", 3),
(null, "乌索普", 1008, "[email protected]", 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);
根据两个表中的记录,返回关联字段相符的记录。也就是求两个表的公共部分(交集)
语法:
# 形式1
# inner可以省略,不加inner默认为内连接
select 字段 from 表1 别名1 inner join 表2 别名2 on 连接条件 and 其他条件;
# 形式2
select 字段 from 表1 别名1, 表2 别名2 where 连接条件 and 其它条件;
示例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 = "迪奥";
查询结果:
示例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;
使用主表的每行数据去匹配从表的数据列,符合连接条件的数据将直接返回到结果集中,对不符合连接条件的列,也就是从表的列将被填上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;
用右边的表作为主表和左边的表进行匹配,如果左边不符合条件,为左表的列填上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;
同一张表和自身进行连接查询
适用于对同一张表中的某些字段进行比较的查询操作
示例:
查询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;
在where子句中包含一个形如select-from-where的查询块,这种查询语句称之为子查询,
也就是将一个查询结果的输出作为另一个查询结果的输入。
返回一行记录的子查询
示例:
查询和路飞同班级的同学信息
select * from student where class_id =
(select class_id from student where name = "路飞");
返回多行记录的子查询
两种形式的查询语句:
in表示字段在这个集合中,not in表示不在集合中
示例1:
查询c++课程和linux课程的成绩信息
select * from score where course_id
in (select id from course where name = "c++"
or name = "linux");
查询结果:
示例2:
查询课程不是c++课程和linux课程的成绩信息
select * from score where course_id
not in (select id from course where name = "c++" or name = "linux");
将查询语句的每一行数据拿出来和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);
查询结果:
示例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);
合并多个查询的执行结果,使用集合操作符union和union all,但是前后查询的结果集中,字段需要一致
取两个结果集的并集,当结果集中有重复行时,会自动去重
示例:
查询id != 2 或者 名字为c++的课程
select * from course where id != 2
union
select * from course where name = "c++";
取两个结果集的并集,当结果集中有重复行时,不会去重
示例:
查询id != 2 或者 名字为c++的课程
select * from course where id != 2
union all
select * from course where name = "c++";