- 多表设计
数据表与数据表之间关系三种:实体之间关系 多对多、一对多、一对一
(1)多对多案例:项目和程序员
一个项目可以由多个程序员参与
一个程序员可以参与多个项目开发
建表原则:多对多关系,必须引入第三张数据表,同时引入另两张实体表主键作为外键
(2)一对多案例:老师与课程
一个老师可以教授多门课程
一门课程只能有一个老师教授
建表原则:一对多关系,在多的一方添加一方 主键作为外键
(3)一对一关系:班级与班长关系
一个班只能有一个班长
一个班长只能负责一个班
* 该关系比较少见
建表原则:一对一关系,可以在任何一方添加 另一方主键作为外键
关系表表名,通常用两个实体表表名组合而成
2. 笛卡尔积
当两个数据表进行关联查询时,用第一张数据表每一条记录去匹配第二张数据表每一条记录。
第一张表10条数据
第二张表20条数据
使用笛卡尔积 结果 10*20 = 200 条记录
在实际开发中,获得笛卡尔积中有意义的记录 ? —- 连接查询 (内连接,外连接)
(1)内连接 : 将两张表相同意义字段连接起来
select * from A,B where A.A_ID = B.A_ID; 条件 A表中A_ID与 B表中 A_ID 相等匹配
* 返回结果一定是两个表都存在信息 , 最有意义的信息,如果第一张表记录在第二张表找不到匹配信息,不显示,第二张表记录在第一张表无匹配信息,不显示
语法:select * from a inner join b on A.A_ID = B.A_ID;
简化:select * from a,b where A.A_ID = B.A_ID;
(2)外连接:左外连接、右外连接、全外连接
左外连接 :用第一张表每条记录去匹配第二张表对应记录,无论是否找到匹配信息,都显
select * from a left outer join b on A.A_ID = B.A_ID ;
右外连接:从第二张表找第一张表匹配记录,无论是否找到,第二张表所有记录都显示
select * from a right outer join b on A.A_ID = B.A_ID ;
全外连接:左外连接与右外连接 结果和 —- 排除重复数据
select * from a full outer join b on A.A_ID = B.A_ID ; —– MySQL 不支持
使用union关键字实现全外连接效果
select * from A left outer join B on A.A_ID = B.A_ID
union
select * from A right outer join B on A.A_ID = B.A_ID;
3.关联子查询
关联子查询:将第一个查询结果 ,作为第二个查询条件 ,查询student表中年龄最大学员的信息
select * from student where age = (select max(age) from student);
等价于 select max(age) from student; —– 25
select * from student where age = 25; —– 学生信息
(1)IN/EXISTS 当前查询记录在子查询结果中存在
查询所有成绩小于60分的同学名称
查询studentcource表成绩小于60 所有记录
select student_id from studentcource where score < 60; — 小于60分学生学号 2,8
再根据id去查询学生表,得知学生姓名
select * from student where id in(2,8);
select * from student where id in(select student_id from studentcource where score < 60);
exists实现上面in 语句效果
select name from student where exists (select * from studentcource where score < 60 and student.id = studentcource.student_id);
select * from studentcource,student where score < 60 and student.id = studentcource.student_id;
select name from student where exists (select * from studentcource where score < 60 and student.id = studentcource.student_id);
* 在实际开发中 exists比 in效率要高
(2)ANY、SOME、ALL 用法
SOME和ANY作用相同的 —– 一些 >any(1,2,3) 大于任何一个都可以 等价于 >min
ALL —- 所有 >all(1,2,3) 必须同时大于三个值 等价于 >max
查询获得最高分的学生学号
select max(score) from studentcource; 最高学分
select student_id from studentcource where score = (select max(score) from studentcource);
* 自我比较
select student_id from studentcource where score >=all(select score from studentcource);
查询编号2课程比编号1课程成绩高所有学号
select score from studentcource where cource_id = 2 and score > any(select score from studentcource where cource_id = 1);
select score from studentcource where cource_id = 2; 课程2所有成绩
select score from studentcource where cource_id = 1; 课程1所有成绩
使用union将两个查询结果合并,union 排重重复数据 union all 不会排重重复数据
* 合并时列名必须一致