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;

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

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

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

相关推荐
耶叶4 分钟前
数字逻辑实验0:verilog语法和代码初步学习
学习
Cat_Rocky6 分钟前
Linux学习-Zabbix 7
学习·zabbix
炽烈小老头12 分钟前
【每天学习一点算法 2026/05/20】省份数量
学习·算法
清平乐的技术专栏20 分钟前
【Flink学习】(七)Flink 状态编程入门,有状态实时计算
大数据·学习·flink
Python大数据分析@37 分钟前
现在怎么去学习AI,在哪里去学习?
人工智能·学习
星幻元宇VR41 分钟前
VR地震模拟平台|打造沉浸式防震减灾科普新模式
科技·学习·安全·vr·虚拟现实
咸甜适中43 分钟前
rust语言学习笔记Trait(六) FromIterator(由迭代器创建集合)
笔记·学习·rust
星幻元宇VR1 小时前
VR安全带防坠落体验平台助力高空作业安全培训
科技·学习·安全·vr·虚拟现实
周淳APP1 小时前
微前端核心沙箱机制深度解析:从iframe到乾坤沙箱
前端·学习·iframe·微前端·qiankun·前端架构
@杰克成1 小时前
Java学习31
java·学习·adb