声明:以下内容为根据黑马数据库视频教程,个人整理的笔记,方便记录学习。
知识导图
案例SQL语句编写
多表关系
一对多
部门与员工
实现:在多的一方建立外键,指向一的一方的主键
create table emp(
id int auto_increment comment 'ID' primary key,
name varchar(50) not null comment '姓名',
age int comment '年龄',
job varchar(20) comment '职位',
salary int comment '薪资',
entrydate date comment '入职时间',
managerid int comment '直属领导ID',
dept_id int comment '部门ID',
constraint fk_dept_id foreign key (dept_id) references dept (id)
)comment '员工表';
多对多
学生 与 课程
实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
create table student_course(
id int auto_increment primary key comment '关系唯一标识',
studentid int not null comment '学生id',
courseid int not null comment '课程id',
constraint fk_studentid foreign key (studentid) references student (id),
constraint fk_courseid foreign key (courseid) references course (id)
) comment '学生课程中间表';
一对一
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
多表查询
内连接
查询绿色部分数据
emp表如下:(其中,dept_id字段是外键,关联到dept表的id字段)
dept表如下:
案例:
A. 查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
select emp.name,dept.name from emp,dept where emp.dept_id=dept.id;
或
-- 为每一张表起别名,简化SQL编写
select e.name,d.name from emp e,dept d where e.dept_id=d.id;
B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现)
select emp.name,dept.name from emp inner join dept on emp.dept_id=dept.id;
或
-- 为每一张表起别名,简化SQL编写
select e.name,d.name from emp e inner join dept d on e.dept_id=d.id;
或
-- inner字段可以省略
select e.name,d.name from emp e join dept d on e.dept_id=d.id;
注意:
一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段。
外连接
A. 查询emp表的所有数据, 和对应的部门信息
select e.*, d.name from emp e left outer join dept d on e.dept_id = d.id;
-- 或 outer 省略掉为
select e.*, d.name from emp e left join dept d on e.dept_id = d.id;
B. 查询dept表的所有数据, 和对应的员工信息
select d.*, e.* from dept d left outer join emp e on e.dept_id = d.id;
自连接
自连接查询
A. 查询员工 及其 所属领导的名字
select a.name , b.name from emp a , emp b where a.managerid = b.id;
B. 查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid =b.id;
注意:在自连接查询中,必须要为表起别名。
联合查询
将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来
select * from emp where salary < 5000
union all
select * from emp where age > 50;
再去重:
select * from emp where salary < 5000
union
select * from emp where age > 50;
子查询
emp表如下:(其中,dept_id字段是外键,关联到dept表的id字段)
dept表如下:
标量子查询
A. 查询 “销售部” 的所有员工信息
select * from emp where dept_id = (select id from dept where name = '销售部');
B. 查询在 “方东白” 入职之后的员工信息
select * from emp where entrydate > (select entrydate from emp where name = '方东白');
列子查询
A. 查询 “销售部” 和 “市场部” 的所有员工信息
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
B. 查询比 财务部 所有人工资都高的员工信息
select * from emp where salary > all ( select salary from emp where dept_id =(select id from dept where name = '财务部') );
C. 查询比研发部其中任意一人工资高的员工信息
select * from emp where salary > any ( select salary from emp where dept_id =(select id from dept where name = '研发部') );
行子查询
查询与 “张无忌” 的薪资及直属领导相同的员工信息
select * from emp where (salary,managerid) = (select salary,managerid from emp where name='张无忌')
表子查询
A. 查询与 “鹿杖客” , “宋远桥” 的职位和薪资相同的员工信息
select * from emp where (job,salary) in ( select job, salary from emp where name ='鹿杖客' or name = '宋远桥' );
B. 查询入职日期是 “2006-01-01” 之后的员工信息 , 及其部门信息
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id ;