目录
1、数据库的约束
(1)约束的基本类型
(2)default约束
(3)primary key:主键约束
(4)foreign key:外键约束
2、表的设计
3、新增
4、查询
(1)聚合查询
5、联合查询
(1)内连接
(2)外连接
(3)自连接
(4)子查询
(5)合并查询
- not null:指定该列不能存储null值;
- unique:表示该列的每一行的值不能重复(null除外);
- default:设置该列的默认值;
- primary key:not null和unique的结合。确保该列有唯一的标识。帮助查找表中的特定记录。
- foreign key:保证一个表中的数据匹配另一个表中的值的参照完整性;
- check:保证列中的值符合指定的条件。(mysql没有实现这个约束,但是使用时不会报错)
name不指定值时,默认为unkown:
CREATE TABLE student (
id INT NOT NULL,
sn INT UNIQUE,
name VARCHAR(20) DEFAULT 'unkown',
qq_mail VARCHAR(20)
);
【注】只有在不插入值时,才会生效,即使插入的值为null,也不生效。
指定id列为主键(主键字段不插入或者插入重复的字段都会报错):
CREATE TABLE student (
id INT NOT NULL PRIMARY KEY,
sn INT UNIQUE,
name VARCHAR(20) DEFAULT 'unkown',
qq_mail VARCHAR(20)
);
对于整数类型的主键,可以搭配自增auto_increment(是mtsql的关键字,不是sql标准)使用。插入数据的对应字段不设置值时,使用最大值(不是插入的最大值,而是mysql记录的最大值)+1。
-- 主键是 NOT NULL 和 UNIQUE 的结合,可以不用 NOT NULL
id INT PRIMARY KEY auto_increment,
外键用于关联其他表的主键或唯一键。(用于设计表与表之间的关系)
(1)一对一的关系(人和身份证就是一对一的关系)
(2)一对多关系(一个班级有多个学生,班级和学生就是一对多的关系)
(3)多对多关系
多对多关系,表的设计:
在表的结构上,只有两个一对多的关系。数据上体现出两个一对多,以及逻辑上的多对多关系。
插入查询结果
-- 此时表一和表二的字段需要相对应,数量、类型一一对应,表一中插入的是表二中查询到的数据
insert into 表名1(字段1,字段2……)
select 字段1,字段2…… from 表名2 [where][order by]
函数 | 说明 |
count() | 计数器,返回查询到的数据个数 |
sum() | 返回查询到的数据的和(不是数字没有意义) |
avg() | 返回查询到数据的平均值(不是数字没有意义) |
max() | 返回查询到的数据的最大值(不是数字没有意义) |
min() | 返回查询到的数据的最小值(不是数字没有意义) |
count:count(*)=count(字段名)=count(常量值)如:count(0);查询的时候使用了聚合函数,后面就不要再跟具体的字段了。(发生了聚合操作后,后面的字段就没有意义,mysql默认显示第一条数据,其它数据库会报错)
【注】聚合是在查询返回结果集后,再进行聚合的
-- 分组查询select中只能出现分组依据字段,其他字段要想出现在select中,必须使用聚合函数
select 列名1,sum(列名2)…… from 表名 group by 列名1;
group by子句进行分组后,需要对分组结果再进行条件过滤时,不能使用where语句,需要用having。(分组后的条件过滤)
笛卡尔积的结果是两张表的每条数据相连接,产生的一个结果集(虚拟表)
联合查询:将笛卡尔积产生的结果集进行过滤,留下有意义的数据。
联合查询筛选的条件是进行主外键的关联
为了方便,我们可以使用表的别名,但是要注意,如果表使用了别名,条件筛选的时候字段必须使用别名+字段名的方式,否则会报错。
因为两张表可能存在相同的字段名(查询出来的表在使用的时候会造成很大的不便),所以尽量减少*的使用,可以将所有的字段名列出来。
-- 如果多张表进行连接的时候,第一种使用多个join……on……即可
-- 第二种使用and将所有条件连接起来即可
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;
例:下面就是一个多表的内连接,四张表,学生表、班级表、考试成绩表、课程表,查询所有班级的所有课程的平均分。(描述了两种写法)
-- 查询所有班级所有课程的平均分
select
c.id c_id,
c.name c_name,
cou.name cou_name,
avg(e.score)
from student s, classes c, exam_score e, course cou
where s.classes_id=c.id
and s.id=e.student_id
and e.course_id=cou.id
group by c.id, cou.id;
-- 也可以使用 join on的写法
select
c.id c_id,
c.name c_name,
cou.name cou_name,
avg(e.score)
from student s
join classes c on s.classes_id=c.id
join exam_score e on s.id=e.student_id
join course cou on e.course_id=cou.id
group by c.id, cou.id;
外连接分为左外连接和右外连接。左外连接的左表和右外连接的右表我们称之为外表,外表会被完全显示。
-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件 where 其他条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件 where 其他条件;
外连接和内连接的区别:
- 内连接:只要连接条件不满足,数据便不会显示
- 外连接:即使连接条件不满足,主要外表的连接条件不为空,数据就会显示
连接两张表(学生表和班级表)此时给班级表中插入新数据(i),使用外连接时,因为i对应的学生信息为空,不满足连接条件,此时查询结果不会显示i这个班级信息;而使用内连接,即使此时不满足连接条件,但作为外表的班级表中插入的数据i的连接字段此时不为空,所以内连接会显示该条数据。
自身连接自身进行查询
自连接的应用场景:
对于这张表,我们需要查询语文成绩比数学成绩高的学生的信息:
此时,单表的where条件操作就不能满足要求(只能实现同一行数据之间的操作),此时我们需要进行同一张表中同一个字段不同行数据之间的比较,就要用到自连接。
【代码如下】
-- 使用自连接,第一张表保存语文成绩,第二张表保存数学成绩,进行筛选即可
select
*
from exam_score e1,exam_score e2
where e1.student_id=e2.student_id
and e1.course_id=1
and e2.course_id=2
and e1.score>e2.score;
子查询是指嵌入到其它sql语句中的select语句,也叫嵌套查询。
例:查询‘张三’的同班同学
select * from student where classes_id=(select classes_id from student where name='张三');
(1)in关键字
进行多个字段的查询时,一定要注意查询字段和in前面的字段对应。
(2)exists关键字
(这儿不太会,先放着)
为了合并多个select语句的执行结果,可以使用union、union all,使用时,前后查询的结果集中,字段需要一致。
例:查询id小于3或者name为英文的课程信息。
select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';