MySQL学习(4)——多表操作

多表操作

多表关系

外键约束

一对多的外键约束

创建外键约束

一对多/多对一创建外键约束:

sql 复制代码
create database mydb3;
use mydb3;

CREATE table dept(
deptno int PRIMARY KEY,
dname varchar(20)
);
-- 方式1
CREATE table emp(
id int PRIMARY KEY,
pname varchar(20),
age int,
cid int,
constraint dep_fk FOREIGN KEY(cid) REFERENCES dept(deptno) 
);

CREATE table emp(
id int PRIMARY KEY,
pname varchar(20),
age int,
cid int
);
-- 方式2
alter table emp ADD CONSTRAINT dep_fk FOREIGN KEY(cid) REFERENCES dept(deptno);

多对多创建外键约束:

sql 复制代码
CREATE table student(
sid int PRIMARY KEY,
sname varchar(20)
);

CREATE table class(
cid int PRIMARY KEY,
cname varchar(20)
);

CREATE table score(
sid int,
cid int,
score int
);
alter table score add CONSTRAINT s_key FOREIGN KEY(sid) REFERENCES student(sid);
alter table score add constraint c_key FOREIGN KEY(cid) REFERENCES class(cid);

alter table score drop FOREIGN key s_key;
alter table score drop FOREIGN key c_key;

在外键约束下的数据操作

1.必须先给主表 添加数据,再给从表 添加数据。

2.从表 中有外键约束那一列不能随便写,只能写主表 中有的内容。

3.删除数据时:

主表 的数据被从表 依赖时不能删除,否则可以删除。

从表的数据可以随便删除。

删除外键约束

多表联合查询

外键约束对于多表查询并没有影响。

在下面表格的基础上学习多表查询:

sql 复制代码
-- 多表查询
CREATE table dept2(
deptno VARCHAR(20),
name varchar(20)
);

CREATE table emp2(
eid VARCHAR(20) PRIMARY KEY,
ename varchar(20),
age int,
dept_id varchar(20)
);
insert into dept2 values('1001','研发部'),('1002','销售部'),('1003','财务部'),('1004','人事部');
insert into emp2 values('1','乔峰',20,'1001');
insert into emp2 values('2','段誉',21,'1001');
insert into emp2 values('3','虚竹',23,'1001');
insert into emp2 values('4','阿紫',18,'1001');
insert into emp2 values('5','扫地僧',85,'1002');
insert into emp2 values('6','李秋水',33,'1002');
insert into emp2 values('7','鸠摩智',50,'1002');
insert into emp2 values('8','天山童姥',60,'1003');
insert into emp2 values('9','慕容博',58,'1003');
insert into emp2 values('10','丁春秋',71,'1005');

运行后会得到两张表:

dept2:

emp2:

交叉连接查询
内连接查询

练习:

-- 查询每个部门的所属员工-- 隐式查询-- 显示查询

-- 查询研发部门的所属成员

-- 查询研发部门和销售部的所属成员

-- 查询每个部门的员工数

-- 查询员工数大于等于2的部,并降序排列

答案:

sql 复制代码
-- 内连接查询
-- 隐式查询
select * from dept2,emp2 where dept2.deptno=emp2.dept_id;
-- 显示查询
select * from dept2 JOIN emp2 on dept2.deptno=emp2.dept_id;

-- 查询研发部门的所属成员
select * from dept2 join emp2 on dept2.deptno=emp2.dept_id and dept2.name = '研发部';
-- 查询研发部门和销售部的所属成员
select * from dept2 join emp2 on dept2.deptno=emp2.dept_id and dept2.name in ('研发部','销售部');
-- 查询每个部门的员工数
select deptno,count(*) from dept2 join emp2 on dept2.deptno=emp2.dept_id GROUP BY dept2.deptno;
-- 查询员工数大于等于2的部,并降序排列
select deptno,count(*) cnt from dept2 join emp2 on dept2.deptno=emp2.dept_id GROUP BY dept2.deptno having cnt>=3 order by cnt desc;
外连接查询
sql 复制代码
-- 查询哪些部门有员工,哪些部门没有员工
SELECT * from dept2 left join emp2 on dept2.deptno=emp2.dept_id;
-- 查询哪些员工有部门,哪些员工没有部门
SELECT * from dept2 right join emp2 on dept2.deptno=emp2.dept_id;
-- 使用union关键字实现左外连接和右外连接的并集
SELECT * from dept2 left join emp2 on dept2.deptno=emp2.dept_id
UNION
SELECT * from dept2 right join emp2 on dept2.deptno=emp2.dept_id;

-- 查询哪些部门有员工,哪些部门没有员工:代码运行结果

-- 查询哪些员工有部门,哪些员工没有部门:代码运行结果

-- 使用union关键字实现左外连接和右外连接的并集:代码运行结果

子查询
sql 复制代码
-- 查询年龄最大的员工信息,显示信息包含员工号、员工名字,员工年龄
select * from emp2 where age=(select max(age) from emp2);
-- 查询研发部和销售部的员工信息,包含员工号、员工名字
-- 方式1------关联查询
select eid,ename from emp2 JOIN dept2 on emp2.dept_id = dept2.deptno and name in ('研发部','销售部');
-- 方式2------子查询
select eid,ename from emp2 where dept_id in (select deptno from dept2 where name in ('研发部','销售部'));
-- 查询研发部30岁以下的员工信息,包括员工号、员工名字,部门名字
-- 方式1------关联查询
select eid,ename,name from emp2 JOIN dept2 on emp2.dept_id = dept2.deptno and (name='研发部' and age<30);
-- 方式2------子查询
-- 2.1 在部门表中查询研发部信息
select * from dept2 where name='研发部';
-- 2.2 在员工表中查询年龄小于30岁的员工信息
select * from emp2 where age<30;
-- 2.3 将上面两个查询结果进行关联查询
select * from (select * from dept2 where name='研发部') t1 join (select * from emp2 where age<30) t2 on t1.deptno=t2.dept_id;
  • 子查询关键字:all、any、some、in、exists
自关联查询
sql 复制代码
create table t_sanguo(
eid int PRIMARY KEY,
name VARCHAR(20),
manager_id int,
FOREIGN KEY (manager_id) references t_sanguo(eid)
);

insert into t_sanguo values(1,'刘协',NULL);
insert into t_sanguo values(2,'刘备',1);
insert into t_sanguo values(3,'关羽',2);
insert into t_sanguo values(4,'张飞',2);
insert into t_sanguo values(5,'曹操',1);
insert into t_sanguo values(6,'许褚',5);
insert into t_sanguo values(7,'典韦',5);
insert into t_sanguo values(8,'孙权',1);
insert into t_sanguo values(9,'周瑜',8);
insert into t_sanguo values(10,'鲁肃',8);
-- 查找员工和对应的上级
select t1.name '员工',t2.name '上级' from t_sanguo t1,t_sanguo t2 where t1.manager_id=t2.eid;
-- 查找所有员工和对应的上级
select a.name '员工',b.name '上级' from t_sanguo a left join t_sanguo b on a.manager_id=b.eid;
-- 查找所有员工对应的上级和上上级
select 
   a.name '员工',b.name '上级',c.name '上上级' 
from t_sanguo a 
	 left join t_sanguo b on a.manager_id=b.eid 
	 left join t_sanguo c on b.manager_id=c.eid;

查找员工和对应的上级:运行结果

查找所有员工和对应的上级:运行结果

查找所有员工对应的上级和上上级:运行结果

相关推荐
im_AMBER3 小时前
编辑器项目开发复盘:主题切换
前端·学习·前端框架·编辑器·html5
2401_865721333 小时前
WEEK 3 刷题&学习记录
网络·学习·ctf
好奇龙猫6 小时前
【日语学习-日语知识点小记-日本語体系構造-JLPT-N2前期阶段-第一阶段(19):単語文法】
学习
Nan_Shu_61410 小时前
学习: 尚硅谷Java项目之小谷充电宝(3)
java·后端·学习
头疼的程序员10 小时前
计算机网络:自顶向下方法(第七版)第三章 学习分享(二)
网络·学习·计算机网络
星期五不见面10 小时前
AI学习(三)openclow启动(2)2026/03/05
学习
weixin_4434785110 小时前
flutter组件学习之Flex / Expanded弹性布局组件
javascript·学习·flutter
im_AMBER10 小时前
Leetcode 136 最小栈 | 逆波兰表达式求值
数据结构·学习·算法·leetcode·
Xzq21050910 小时前
网络基础学习(一)
网络·学习