1、概述

(1)一对多

(2)多对多

数据:
create table student(
id int auto_increment key comment '主键ID',
name varchar(10) comment '姓名',
no varchar(10) comment '学号'
)comment ' 学生表';
insert into student values (null,'黛绮丝','2000100101'),(null,'谢逊','2000100102'),(null,'殷天正','2000100103'),(null,'韦一笑','2000100104');
create table course(
id int auto_increment key comment '主键ID',
name varchar(10) comment '课程名称'
)comment '课程表';
insert into course values (null,'Java'),(null,'PHP'),(null,'Mysql'),(null,'Hadoop');
create table student_course(
id int auto_increment comment '主键' key,
studentid int not null comment '学生ID',
courseid int not null comment '课程ID',
constraint fk_courseid foreign key (courseid) references course(id),
constraint fk_studentid foreign key (studentid) references student(id)
)comment '学生课程中间表';
insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,3),(null,3,4);
创建了学生表、课程表以及两个表之间的关联表,一下主要通过id进行关联

(3)一对一

数据:
create table tb_user(
id int auto_increment key COMMENT '主键ID',
name varchar(10) COMMENT '姓名',
age int COMMENT '年龄',
gender char(1) COMMENT '1:男, 2:女',
phone char(11) COMMENT '手机号'
)comment '用户基本信息表';
create table tb_user_edu(
id int auto_increment primary key COMMENT '主键ID',
degree varchar(20) COMMENT '学历',
major varchar(50) COMMENT '专业',
primaryschool varchar(50) COMMENT '小学',
middleschool varchar(50) COMMENT '中学',
university varchar(50) COMMENT '大学',
userid int unique COMMENT '用户ID',
constraint fk_userid foreign key (userid) references tb_user(id)
)comment '用户教育信息表';
insert into tb_user(id,name,age,gender,phone) values
(null,'黄渤',45,'1','18800001111'),
(null,'冰冰',35,'2','18800002222'),
(null,'码云',55,'1','18800008888' ),
(null,'李彦宏',50,'1','18800009999');
insert into tb_user_edu(id, degree, major, primaryschool, middleschool, university, userid) values
(null,'本科','舞蹈','静安区第一小学','静安区第一中学','北京舞蹈学院',1),
(null,'硕士','表演','朝阳区第一小学','朝阳区第一中学','北京电影学院',2),
(null,'本科','英语','杭州市第一小学','杭州市第一中学','杭州师范大学',3),
(null,'本科','应用数学','阳泉第一小学','阳泉区第一中学','清华大学',4);
2、多表查询

select * from empp,dept where empp.dept_id=dept.id;
加上一个条件即可消除


(1)内连接

习题:(a)

select empp.name,dept.name from empp,dept where empp.dept_id=dept.id;

(b)
select empp.name,dept.name from empp join dept on empp.dept_id=dept.id;
结果依然如上所示
同一个题的两种显示方式!!!
(2)外连接

以左连接为例,将A和B连接之后,如果选择左连接,就返回A表和B表相连接之后的整个信息表,并且以A表的数据为主,B表如果没有A表相对应的内容就置为NULL
习题:(a)

select empp.*,dept.name from empp left join dept on empp.dept_id=dept.id;

(b)

select dept.*,empp.* from empp right join dept on empp.dept_id=dept.id;

(3)自连接

习题:(a)


select a.name,b.name from empp a join empp b on a.managerid=b.id;
自连接的时候最好起别名,不然不太好区分

(b)

select a.name,b.name from empp a left join empp b on a.managerid=b.id;

(4)联合查询

习题:

select * from empp where salary<10000
union all
select * from empp where age>50;
这里因为表的数据较少,因此将薪资改为10000,题目的意思是将薪资低于10000的和年龄大于50的都罗列出来,使用union all实现这个功能

并且union的时候只要上面符合条件的人出现过一次,下面的表就不显示
union all则相当于上面一个表,下面一个表,将两个表进行拼接得到的
并且上下两个字段列表的数量要一致

(5)子查询


(a)标量子查询

习题:(a)

select id from dept where name='销售部';#先查找销售部的部门id
select * from find where dept_id=4;#一一对应将属于销售部的员工信息进行罗列

(b)

select * from find where entrydate>(select entrydate from find where name='方东白');

(b)列子查询

习题:(a)

select * from find where dept_id in(select id from dept where name='销售部' or name='市场部');

(b)查询条件都满足才返回

select * from find where salary>(select max(salary) from find where dept_id=(select id from dept where name='财务部' ));
或者:


(c)任意一个满足条件就返回

select * from find where salary >any(select salary from find where dept_id=(select id from dept where name='研发部'));

(c)行子查询

习题:返回结果为一行多列!

select * from find where (salary,managerid)=(select salary,managerid from find where name='张无忌');

(d)表子查询

习题:(a)多行多列对应,在上述的基础上将等号变成in,代表只要有一个满足即可!!!

select * from find where (job,salary) in (select job,salary from find where name ='鹿杖客'or name='宋远桥');

(b)直接将中间的表放到from后面进行查询!

select * from(select * from find where entrydate>'2006-01-01') f left join dept on f.dept_id=dept.id;

3、综合练习1

(1)
select f.name,f.age,f.job,d.name from find f,dept d where f.dept_id=d.id;

(2)
select f.name,f.age,f.job,d.name from find f join dept d on (f.dept_id=d.id) where age<30;

(3)
使用distinct可以去除重复的结果
select distinct d.id,d.name from find f , dept d where f.dept_id=d.id;

(4)一定要注意where后边首先就对数据进行初次删除,如果和on后面的条件互换,那么没有分配部分的员工是展示不出来的,因为在初筛的时候就去掉了!!!
select f.*,d.name from find f left join dept d on f.dept_id=d.id where age>40;

(5)
select f.name,s.grade from find f,salgrade s where f.salary>=s.losal and f.salary<=s.hisal;

(6)
select f.*,s.grade from (select * from find f where dept_id=(select id from dept where name='研发部')) f,salgrade s where (f.salary between s.losal and s.hisal);

(7)
select avg(f.salary)
from find f,
dept d
where f.dept_id = (select id from dept where name = '研发部');

(8)
select * from find f where salary>(select salary from find where name='灭绝');

(9)
select * from find where salary>(select avg(salary) from find);

(10)
select * from find f where f.salary<(select avg(i.salary) from find i where i.dept_id=f.dept_id);

(11)
select id,name,(select count(*)from find f where f.dept_id=d.id)'人数' from dept d;
先查询dept表中的部门信息,之后在展示部分新增一个人数的信息,将每个部门的人数添加进去即可

(12)
select s.name '姓名',s.no '学号',c.name '课程名' from student s,course c,student_course sc where sc.studentid=s.id and sc.courseid=c.id;

总结:
