【 第五章 多表关系,多表查询,内连接,外连接,自连接,联合查询,子查询】

news2024/11/29 8:48:03

第五章 多表关系,多表查询,内连接,外连接,自连接,联合查询,子查询

1.多表关系:
(1)一对多(多对一)

案例: 部门 与 员工的关系
关系: 一个部门对应多个员工,一个员工对应一个部门
实现: 在多的一方建立外键,指向一的一方的主键

在这里插入图片描述
(2)多对多

案例: 学生 与 课程的关系
关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

在这里插入图片描述

对应SQL语句:
use itcast;
create table student(
id int auto_increment primary 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 primary 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 '主键' primary 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,2),(null,2,3),(null,3,4);

(3)一对一

案例: 用户 与 用户详情的关系
关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

在这里插入图片描述

use itcast;
create table tb_user(
id int auto_increment primary 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.多表查询:
(1)数据准备:

-- 创建dept表,并插入数据
use itcast;
create table dept(
id int auto_increment comment 'ID' primary key,
name varchar(50) not null comment '部门名称'
)comment '部门表';
INSERT INTO dept (id, name) VALUES (1, '研发部'), (2, '市场部'),(3, '财务部'), 
(4,'销售部'), (5, '总经办'), (6, '人事部');
-- 创建emp表,并插入数据
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'
)comment '员工表';
-- 添加外键
alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);

INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id)
VALUES(1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),
(2, '张无忌', 20, '项目经理',12500, '2005-12-05', 1,1),
(3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),
(4, '韦一笑', 48, '开发',11000, '2002-02-05', 2,1),
(5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),
(6, '小昭', 19, '程序员鼓励师',6600, '2004-10-12', 2,1),
(7, '灭绝', 60, '财务总监',8500, '2002-09-12', 1,3),
(8, '周芷若', 19, '会计',48000, '2006-06-02', 7,3),
(9, '丁敏君', 23, '出纳',5250, '2009-05-13', 7,3),
(10, '赵敏', 20, '市场部总监',12500, '2004-10-12', 1,2),
(11, '鹿杖客', 56, '职员',3750, '2006-10-03', 10,2),
(12, '鹤笔翁', 19, '职员',3750, '2007-05-09', 10,2),
(13, '方东白', 19, '职员',5500, '2009-02-12', 10,2),
(14, '张三丰', 88, '销售总监',14000, '2004-10-12', 1,4),
(15, '俞莲舟', 38, '销售',4600, '2004-10-12', 14,4),
(16, '宋远桥', 40, '销售',4600, '2004-10-12', 14,4),
(17, '陈友谅', 42, null,2000, '2011-10-12', 1,null);

(2)笛卡尔积: 笛卡尔乘积是指在数学中,两个集合A集合 和 B集合的所有组合情况。
在这里插入图片描述
在多表查询中,我们是需要消除无效的笛卡尔积的,只保留两张表关联部分的数据。
在这里插入图片描述

例如:select * from emp,dept where emp.dept_id=dept.id;

(3)多表查询分类:
在这里插入图片描述①内连接:
内连接查询的是两张表交集部分的数据。
内连接的语法分为两种: 隐式内连接、显式内连接。

(1) 隐式内连接
SELECT 字段列表 FROM1 ,2 WHERE 条件 ... ; 
(2). 显式内连接
SELECT 字段列表 FROM1 [ INNER ] JOIN2 ON 连接条件 ... ; 
表的别名:
①. tablea as 别名1 , tableb as 别名2 ;. tablea 别名1 , tableb 别名2 ;
注意事项:一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段。
案例:
A. 查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
 表结构: emp , dept
 连接条件: emp.dept_id = dept.id
select emp.name,dept.name from emp,dept where emp.dept_id=dept.id;
select e.name,d.name from emp e,dept d where e.dept_id=d.id;
B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现) --- INNER JOIN ...ON ...
 表结构: emp , dept
 连接条件: emp.dept_id = dept.id
select e.name,d.name from emp e inner join dept d on e.dept_id=d.id;

②外连接:
外连接分为两种,分别是:左外连接 和 右外连接。

(1)左外连接
SELECT 字段列表 FROM1 LEFT [ OUTER ] JOIN2 ON 条件 ... ;
左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。
(2)右外连接
SELECT 字段列表 FROM1 RIGHT [ OUTER ] JOIN2 ON 条件 ... ;
右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。
注意事项:
左外连接和右外连接是可以相互替换的,只需要调整在连接查询时SQL中,表结构的先后顺序就可以了。
而我们在日常开发使用时,更偏向于左外连接。
A. 查询emp表的所有数据, 和对应的部门信息
 由于需求中提到,要查询emp的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
 表结构: emp, dept
 连接条件: emp.dept_id = dept.id
select e.*,d.name from emp e left outer join dept  d on e.dept_id=d.id;
B. 查询dept表的所有数据, 和对应的员工信息(右外连接)
 由于需求中提到,要查询dept表的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
 表结构: emp, dept
 连接条件: emp.dept_id = dept.id
 select d.* ,e.* from emp e right outer join dept  d on e.dept_id=d.id;
 select d.*, e.* from dept d left outer join emp e on e.dept_id = d.id;

③自连接:
自连接查询,顾名思义,就是自己连接自己,也就是把一张表连接查询多次。对于自连接查询,可以是内连接查询,也可以是外连接查询。

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ;
注意事项:
在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底是哪一张表的字段。
A. 查询员工 及其 所属领导的名字
 表结构: emp
select a.name,b.name from emp a,emp b where a.managerid=b.id;
B. 查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来
 表结构: emp a , emp b
 select a.name '员工',b.name '领导' from emp a left join emp b on a.managerid=b.id;

④联合查询:
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

SELECT 字段列表 FROM 表A ...
UNION [ ALL ]
SELECT 字段列表 FROM 表B ....;
①对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
②union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。
案例:
A. 将薪资低于 5000 的员工 , 和年龄大于50 岁的员工全部查询出来.
当前对于这个需求,我们可以直接使用多条件查询,使用逻辑运算符 or 连接即可。 那这里呢,我们
也可以通过union/union all来联合查询.
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;

⑤子查询:
SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。

SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 ); 
子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个。

根据子查询结果不同,分为:
A. 标量子查询(子查询结果为单个值)
B. 列子查询(子查询结果为一列)
C. 行子查询(子查询结果为一行)
D. 表子查询(子查询结果为多行多列)
根据子查询位置,分为:
A. WHERE之后
B. FROM之后
C. SELECT之后

A.标量子查询:

子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
常用的操作符:= <> > >= < <=
案例:
A. 查询 "销售部" 的所有员工信息,完成这个需求时,我们可以将需求分解为两步:
①. 查询 "销售部" 部门ID
select id from dept where name='销售部';. 根据 "销售部" 部门ID, 查询员工信息
select *from emp where dept_id=(select id from dept where name='销售部');

B. 查询在 "方东白" 入职之后的员工信息,完成这个需求时,我们可以将需求分解为两步:
①. 查询 方东白 的入职日期
select entrydate from emp where name='方东白';. 查询指定入职日期之后入职的员工信息
select * from emp where entrydate > (select entrydate from emp where name='方东白');

B.列子查询:

子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
常用的操作符:INNOT INANYSOMEALL

在这里插入图片描述

案例:
A. 查询 "销售部""市场部" 的所有员工信息,分解为以下两步:
①. 查询 "销售部""市场部" 的部门ID
select id from dept where name='销售部' or'市场部';. 根据部门ID, 查询员工信息
select * from emp where dept_id in (select id from dept where name='销售部' or'市场部');

B. 查询比 财务部 所有人工资都高的员工信息,分解为以下两步:
①. 查询所有 财务部 人员工资
select salary from emp where dept_id=(select id from dept where name='财务部');. 比 财务部 所有人工资都高的员工信息
select * from emp where salary>all(select salary from emp where dept_id=(select id from dept where name='财务部'));

C. 查询比研发部其中任意一人工资高的员工信息,分解为以下两步:
①. 查询研发部所有人工资
select salary from emp where dept_id=(select id from dept where name='研发部');. 比研发部其中任意一人工资高的员工信息
select * from emp where salary > any (select salary from emp where dept_id=(select id from dept where name='研发部'));

C.行子查询:

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
常用的操作符:=<>INNOT IN
案例:
A. 查询与 "张无忌" 的薪资及直属领导相同的员工信息,这个需求同样可以拆解为两步进行:
①. 查询 "张无忌" 的薪资及直属领导
select salary,managerid from emp where name='张无忌';. 查询与 "张无忌" 的薪资及直属领导相同的员工信息
select * from emp where (salary,managerid)=(select salary,managerid from emp where name='张无忌');

D.表子查询:

子查询返回的结果是多行多列,这种子查询称为表子查询。
常用的操作符:IN
案例:
A. 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息,分解为两步执行:
①. 查询 "鹿杖客" , "宋远桥" 的职位和薪资
select salary,job from emp where name='鹿杖客'or name='宋远桥';. 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
select * from emp where (salary,job) in (select salary,job from emp where name='鹿杖客'or name='宋远桥');

B. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息,分解为两步执行:
①. 入职日期是 "2006-01-01" 之后的员工信息
select * from emp where entrydate>'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;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【springMVC_11_SpringMVC拦截器_ 拦截器的介绍】

1.什么是拦截器 SpringMVC提供了Intercepter拦截器机制&#xff0c;类似于Servlet当中的Filter过滤器&#xff0c;用于拦截用户的请求并作出相应的处理&#xff0c;比如通过拦截器来进行用户权限验证或者用来判断用户是否登录。SpringMVC拦截器是可插拔式的设计&#xff0c;需…

Linux学习笔记(二)

命令 目录中找文件&#xff1a;find压缩tar&#xff1a;tar -cvf xxx.tar 文件解压缩tar&#xff1a;tar -xvf xxx.tar解压缩.gz文件&#xff1a;tar -zxvf xxx.tar.gz压缩.bz2文件&#xff1a;tar -jcvf xxx.tar.bz2解压到指定目录&#xff1a;tar -C 指定目录压缩zip&#xf…

CIFAR-10 数据集简介

文章目录CIFAR-10 简介CIFAR-10 简介 官网&#xff1a;http://www.cs.toronto.edu/~kriz/cifar.html CIFAR-10和CIFAR-100是8000个万小图像数据集的标记子集。它们由Alex Krizhevsky, Vinod Nair和Geoffrey Hinton收集。 CIFAR-10数据集包含60000张32x32彩色图像&#xff0c…

2183440-36-8,APN-C3-PEG4-alkyne 性能稳定功能连接体

一、APN-C3-PEG4-alkyne物理数据&#xff1a; CAS&#xff1a;2183440-36-8 | 中文名&#xff1a;APN-C3-四聚乙二醇-炔基 |英文名&#xff1a; APN-C3-PEG4-alkyne 结构式&#xff1a; 二、APN-C3-PEG4-alkyne试剂反应原理&#xff1a; 西安凯新生物科技有限公司供应的&…

企业上云原来如此简单,华为云带你体验云上风采

随着云计算、大数据、物联网和人工智能等技术的发展&#xff0c;云计算已经成为企业发展不可或缺的基础设施。企业对数字化转型的需求越来越迫切&#xff0c;但由于自身系统无法满足复杂业务上云需求&#xff0c;企业同时也面临着 IT系统复杂、运维复杂等诸多挑战。 基于此种情…

enumerate(),plt绘图,保存json,cv2.resize,baseline

1.enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列&#xff0c;同时列出数据和数据下标&#xff0c;一般用在 for 循环当中。 enumerate(sequence, [start0]) >>>seasons [Spring, Summer, Fall, Winter] >>> list(e…

为什么解决文档管理问题的数字化战略能够推动盈利增长

为什么解决文档管理问题的数字化战略能够推动盈利增长 每一天&#xff0c;世界都变得更加数字化&#xff0c;在我们的个人生活中&#xff0c;这种变化是持续的。 企业如何跟上发展的步伐&#xff1f;答案是&#xff1a;进行改变完成工作的方式、时间和地点&#xff0c;并在整个…

【学习笔记71】数据代理、回调函数和回调地域

一、数据代理 new Proxy(参数一: 代理那个对象)const obj {name: QF001,age: 18}const res new Proxy(obj, {get (target, p) {/*** target 当前代理的那个对象, 在当前案例中就是obj* p proxy会自动遍历对象, 拿到对象每一个key*/return target[p];},set (target, p,…

新课程发布 | 如何用 7 分钟击破 Serverless 落地难点?

当前&#xff0c;Serverless 覆盖的技术场景正在不断变广。Serverless 已在微服务、在线应用、事件驱动、任务处理等众多场景被验证且广泛应用 。当你想要部署一个网站时&#xff0c;需要自己购买服务器并花费时间去维护&#xff0c;造成资源浪费不说&#xff0c;还要耗费精力。…

2.2 Redis中SDS(简单动态字符串) 与C字符串的区别

引言: 根据传统&#xff0c;C语言使用长度N1的字符数组来表示长度为N的字符串&#xff0c;并且字符数组的最后一个元素总是空字符’\0’。 例如,图2-3 就展示了一个值为"Redis"的C字符串。 C语言使用这种简单的字符串表示方式&#xff0c;并不能满足Redis对字符串在…

计算机组成原理习题课第四章-3(唐朔飞)

计算机组成原理习题课第四章-3&#xff08;唐朔飞&#xff09; ✨欢迎关注&#x1f5b1;点赞&#x1f380;收藏⭐留言✒ &#x1f52e;本文由京与旧铺原创&#xff0c;csdn首发&#xff01; &#x1f618;系列专栏&#xff1a;java学习 &#x1f4bb;首发时间&#xff1a;&…

Android面试题——高级开发面试题一

一 面试题概述 请简单的分析一下Android系统启动流程的原理&#xff1f;App启动状态有哪几种&#xff0c;各自的启动流程是怎么样的&#xff1f;当项目中遇到黑白屏问题&#xff0c;你有什么好的解决方案&#xff1f;如何查看方法内的耗时时间与方法分析&#xff1f;介绍一下A…

英国公派访问学者带家属签证经验分享

英国公派访问学者带家属签证经验分享&#xff0c;下面就随知识人网老师一起来看一看。 一、学历学位证书 英国签证中心要求提供&#xff0c;但留服网上似乎没有提及。 要是带家属&#xff0c;家属属于Academic Dependants签证。首先介绍一个总的说法&#xff0c;也是据网友提…

游戏测试是一个怎样的行业?

游戏测试真的是玩游戏吗&#xff1f; 游戏测试和软件测试又有什么区别呢&#xff1f; 游戏测试是不是没有前景&#xff1f;能从事吗&#xff1f; 很多人都关注这个问题&#xff0c;所以接下来我详细给大家来介绍下游戏测试。 为了让大家更有获得感&#xff0c;所以本文的行…

【关于我接触了Uview的Upload】——单图上传,多图上传,遇到的问题总结、直传阿里云Oss

Uview的Upload组件 前言 有很长一段时间没有更新了&#xff0c;由于工作的繁忙导致没有时间写博客&#xff0c;今天在做到公司特殊场景需要用到上传组件并直传阿里云Oss&#xff0c;这里简单讲讲我在完成前端项目中使用到Uview的Upload遇到的问题以及我是如何解决&#xff0c…

百万企业用户选择的华为云云服务器,你不来了解一下吗?

今天&#xff0c;企业对“云”的需求像水、电、天然气一样普遍&#xff0c;华为云服务器作为新产品迅速占领现有主机市场。但市面上云服务器的种类多不胜数&#xff0c;怎样才能选到适合自己的云服务器呢&#xff1f;在这里&#xff0c;我推荐华为云云服务器&#xff0c;因为它…

力扣hot100——第2天:4寻找两个正序数组的中位数、5最长回文子串、10正则表达式匹配

文章目录1.4寻找两个正序数组的中位数1.1.题目1.2.解答1.2.1.直接法&#xff1a;合并数组再求结果1.2.2.分治&#xff1a;无需合并数组1.2.3.log(n)的解法2.5最长回文子串3.10正则表达式匹配3.1.题目3.2.解答1.4寻找两个正序数组的中位数 参考&#xff1a;力扣题目链接&#x…

压力串级控制装置用于气动马达的高精度调节

摘要&#xff1a;气动马达作为一种将压缩空气的压力能转换为旋转机械能的装置&#xff0c;其运行的关键是要进行驱动气体压力的控制。本文介绍了目前气动马达压力控制装置的技术现状&#xff0c;特别指出了现有技术中使用电空变换器存在的不足&#xff0c;介绍了电空变换器的更…

深入理解java虚拟机:类加载及执行子系统的案例

文章目录1. 概述2. Tomcat&#xff1a;正统的类加载器结构3. OSGi&#xff1a;灵活的类加载器架构4. 字节码生成技术与动态代理的实现5. Retrotranslator&#xff1a;跨越JDK版本1. 概述 在Class文件格式与执行引擎这部分里&#xff0c;用户的程序能直接影响的内容并不太多&am…

Tableau数据分析数据可视化分析平台

Tableau数据分析&数据可视化分析平台​ 本文章内涉及的资源包以及素材均来自于互联网&#xff0c;仅供大家用来交流学习与研究使用&#xff0c;努力提升自己的一篇文章。各类安装包以及素材版权归属原版权方所有&#xff0c;版权争议与本人无关&#xff0c;用户本人下载后不…