数据库(MySQL)—— 多表查询

news2024/5/18 13:08:59

数据库(MySQL)—— 多表查询

  • 多表关系
  • 一对多
  • 多对多
  • 一对一
  • 多表查询概述
    • 数据准备
    • 查询形式
    • 笛卡尔积
  • 分类
    • 连接查询
      • 内连接
      • 外连接
        • 左外连接
        • 右外连接
      • 自连接
      • 联合查询

今天我们来进入MySQL中一个非常重要的部分:多表查询

多表关系

多表关系是数据库设计中常见的概念,指的是在关系型数据库中,两个或多个数据表之间存在的关联关系。这些关系可以是一对一(1:1)、一对多(1:N)或多对多(M:N)等类型。多表关系的建立有助于实现数据的规范化存储和高效查询。

  1. 一对一关系(1:1):在这种关系中,一个表中的记录与另一个表中的记录有且仅有一个对应关系。例如,一个学生表(Student)和一个学生详情表(StudentDetail),每个学生都有一个唯一的详情记录,反之亦然。
  2. 一对多关系(1:N):在这种关系中,一个表中的一条记录可以与另一个表中的多条记录相关联。例如,一个班级表(Class)和学生表(Student),一个班级可以有多个学生,但每个学生只能属于一个班级。
  3. 多对多关系(M:N):在这种关系中,一个表中的一条记录可以与另一个表中的多条记录相关联,反之亦然。例如,一个学生表(Student)和一个课程表(Course),一个学生可以选修多门课程,同时一门课程也可以被多个学生选修。为了实现这种关系,通常需要引入一个中间表(如StudentCourse),该表记录学生和课程之间的关联信息。

在数据库设计中,通过定义主键(Primary Key)和外键(Foreign Key)来建立和维护多表关系主键用于唯一标识一个表中的记录,而外键则用于在一个表中引用另一个表的主键。当两个表之间存在关联关系时,可以在一个表的外键列中存储另一个表的主键值,从而实现表的关联查询。

通过合理地设计多表关系,可以提高数据库的查询性能和数据完整性。同时,多表关系也有助于实现数据的逻辑分离和模块化,使得数据库结构更加清晰易懂。

一对多

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

对应的SQL语句如下:

-- 创建emp表
CREATE TABLE emp(
    -- id号
    id      int PRIMARY KEY AUTO_INCREMENT COMMENT '员工id',
    name    VARCHAR(10) UNIQUE COMMENT '员工姓名',
    age     TINYINT UNSIGNED COMMENT '员工年龄',
    dept_id TINYINT UNSIGNED COMMENT '部门编号',
    -- 外键
    CONSTRAINT fk_key_dept_id FOREIGN KEY(dept_id) REFERENCES
    dept(id)
)COMMENT '员工表';

-- 部门表
CREATE TABLE dept(
  id TINYINT UNSIGNED PRIMARY KEY  COMMENT '部门编号',
  name VARCHAR(10) COMMENT '部门名字'
)COMMENT '部门表';

在这里插入图片描述

多对多

  • 案例: 学生 与 课程的关系
  • 关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择
  • 实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
CREATE TABLE students(
    id int UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
    name VARCHAR(10) UNIQUE COMMENT '学生姓名',
    no int UNSIGNED UNIQUE COMMENT '学生学号'
)COMMENT '学生表';

-- 选课表
CREATE TABLE courses(
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
    name VARCHAR(10) COMMENT '课程名字'
)COMMENT '选课表';

-- 中间表
CREATE TABLE stu_cour(
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
    studentid int UNSIGNED NOT NULL COMMENT '学生ID',
    courseid int  NOT NULL COMMENT '课程ID',

    -- 外键
    CONSTRAINT fk_stu_no FOREIGN KEY (studentid) REFERENCES
    students(id),
    CONSTRAINT  fk_cour_no FOREIGN KEY (courseid) REFERENCES
    courses(id)
)COMMENT '学生选课详情表';

在这里插入图片描述

一对一

  • 案例: 用户 与 用户详情的关系
  • 关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
  • 实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
CREATE TABLE tb_user(
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
    age TINYINT UNSIGNED COMMENT '年龄',
    name VARCHAR(10) NOT NULL COMMENT '姓名',
    gender char(1) NOT NULL COMMENT '性别',
    phone char(11) UNIQUE COMMENT '电话号码'
)COMMENT '用户基本信息表';

CREATE TABLE tb_user_edu(
  id int PRIMARY KEY AUTO_INCREMENT COMMENT '序号',
  degree VARCHAR(10) NOT NULL COMMENT '学历',
  major VARCHAR(10) NOT NULL COMMENT '学位',
  primaryschool VARCHAR(20) NOT NULL COMMENT '小学',
  middleschool VARCHAR(20) NOT NULL COMMENT '中学',
  university VARCHAR(20) NOT NULL COMMENT '大学',
  userid int UNIQUE COMMENT '用户编号',
  CONSTRAINT fk_to_id 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);

在这里插入图片描述

多表查询概述

数据准备

删除之前 emp, dept表的测试数据
执行如下脚本,创建emp表与dept表并插入测试数据

DROP TABLE IF EXISTS emp,dept;
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);

查询形式

原来查询单表数据,执行的SQL形式为:select * from emp;

那么我们要执行多表查询,就只需要使用逗号分隔多张表即可,如: select * from emp , dept; 具体的执行结果如下:
在这里插入图片描述
此时,我们看到查询结果中包含了大量的结果集,总共102条记录,而这其实就是员工表emp所有的记录
(17) 与 部门表dept所有记录(6) 的所有组合情况,这种现象称之为笛卡尔积。接下来,就来简单介绍下笛卡尔积。

笛卡尔积

笛卡尔积(Cartesian Product)是数学中的一个概念,它表示两个集合A和B的所有可能的有序对的集合。用符号表示为A × B,其中“×”表示笛卡尔积运算。具体来说,A × B = {(a, b) | a ∈ A 且 b ∈ B}

例如,设集合A = {1, 2},集合B = {a, b, c},则A × B = {(1, a), (1, b), (1, c), (2, a), (2, b), (2, c)}。

在这里插入图片描述
而在多表查询中,我们是需要消除无效的笛卡尔积的,只保留两张表关联部分的数据。
在这里插入图片描述
在SQL语句中,如何来去除无效的笛卡尔积呢? 我们可以给多表查询加上连接查询的条件即可:

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

在这里插入图片描述

分类

连接查询

  • 内连接:相当于查询A、B交集部分数据
  • 外连接
    左外连接:查询左表所有数据,以及两张表交集部分数据
    右外连接:查询右表所有数据,以及两张表交集部分数据
    自连接:当前表与自身的连接查询,自连接必须使用表别名

我们先来介绍内连接:

内连接

在这里插入图片描述
内连接的语法分为两种: 隐式内连接、显式内连接。先来学习一下具体的语法结构。

隐式内连接:

SELECT 字段列表 FROM1 ,2 WHERE 条件 ... ;

显式内连接:

SELECT 字段列表 FROM1 [ INNER ] JOIN2 ON 连接条件 ... ; 1

案例:

A. 查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
表结构: emp , dept
连接条件: emp.dept_id = dept.id

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. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现) — INNER JOIN …ON …
表结构: emp , dept
连接条件: emp.dept_id = dept.id

select emp.name,dept.id
from emp inner join
dept on emp.dept_id = dept.id;

在这里插入图片描述

表的别名:
tablea as 别名1 , tableb as 别名2 ;
tablea 别名1 , tableb 别名2 ;

外连接

在这里插入图片描述
外连接分为两种,分别是:左外连接 和 右外连接。具体的语法结构为:

左外连接

案例:
A. 查询emp表的所有数据, 和对应的部门信息
由于需求中提到,要查询emp的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
表结构: emp, dept
连接条件: emp.dept_id = dept.id

SELECT 字段列表 FROM1 LEFT [ OUTER ] JOIN2 ON 条件 ... ;

左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。

select * from
emp left join
dept on emp.dept_id = dept.id;

在这里插入图片描述

右外连接

案例

查询dept表的所有数据, 和对应的员工信息(右外连接)
由于需求中提到,要查询dept表的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
表结构: emp, dept
连接条件: emp.dept_id = dept.id

SELECT 字段列表 FROM1 RIGHT [ OUTER ] JOIN2 ON 条件 ...; 

在这里插入图片描述

注意事项:
左外连接和右外连接是可以相互替换的,只需要调整在连接查询时SQL中,表结构的先后顺序就可以了。而我们在日常开发使用时,更偏向于左外连接。

自连接

自连接查询,顾名思义,就是自己连接自己,也就是把一张表连接查询多次。我们先来学习一下自连接的查询语法:

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;

或者这样也行:

select a.name,b.name from emp a
inner join emp b
on a.managerid = b.id;

在这里插入图片描述

查询所有员工 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来联合查询.

在这里插入图片描述
union all查询出来的结果,仅仅进行简单的合并,并未去重。

select * from emp where salary < 5000
union
select * from emp where age > 50;

在这里插入图片描述
union 联合查询,会对查询出来的结果进行去重处理。

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

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

相关文章

【HM】DevEco Studio如何使用代码编程AI助手

大家可能都有用过或了解过github copilot插件&#xff0c;确实为我们编码智能、提升开发效率有很大的帮助。推荐两款国产的ai编程插件&#xff0c;分别是华为的CodeArts Snap和阿里的通义灵码。 DevEco 中如何安装通义灵码&#xff1f; 一、下载通义灵码离线安装包 打开官网…

数组邻接表+堆优化版dijkstra+蓝桥杯2022年第十三届决赛真题-出差

文章目录 邻接表数组实现堆优化版dijkstra蓝桥杯2022年第十三届决赛真题-出差 邻接表数组实现 idx是每条边的地址e保存终点的节点值w保存每条边的权值ne[idx]保存边表&#xff0c;idx的下一个顶点的地址h[a]保存顶点表&#xff0c;a是起点&#xff0c;h[a]是终点的地址 int e…

docker-compose单机容器集群编排工具

前言&#xff1a; docker-compose用来单机上编排容器&#xff08;定义和运行多个容器&#xff0c;使容器能互通&#xff09; Eg&#xff1a;前端和后端部署在一台机器上&#xff0c;现在直接通过编写docker-compose文件对多个服务&#xff08;可定义依赖&#xff0c;按顺序启…

conda环境安装的pyproj包报错

conda环境安装的pyproj包报错 文章目录 conda环境安装的pyproj包报错问题解决参考 问题 在conda创建的Python3.9虚拟环境中安装pyproj包3.6在运行时出现以下报错 UserWarning: pyproj unable to set database path. _pyproj_global_context_initialize()解决 先激活并进入创…

古典密码学简介

目录 C. D. Shannon: 一、置换密码 二、单表代替密码 ① 加法密码 ② 乘法密码 ③密钥词组代替密码 三、多表代替密码 代数密码 四、古典密码的穷举分析 1、单表代替密码分析 五、古典密码的统计分析 1、密钥词组单表代替密码的统计分析 2、英语的统计规…

从零开始学AI绘画,万字Stable Diffusion终极教程(二)

【第2期】关键词 欢迎来到SD的终极教程&#xff0c;这是我们的第二节课 这套课程分为六节课&#xff0c;会系统性的介绍sd的全部功能&#xff0c;让你打下坚实牢靠的基础 1.SD入门 2.关键词 3.Lora模型 4.图生图 5.controlnet 6.知识补充 在第一节课里面&#xff0c;我们…

【数据库原理及应用】期末复习汇总高校期末真题试卷

试卷 一、填空题 1.________是位于用户与操作系统之间的一层数据管理软件。 2.数据库系统的三级模式结构是指________、________、________。 3.数据库系统的三种数据模型是________ 、________、________。 4.若关系中的某一属性组的值能唯一地标识一个元组&#xff0c;则…

【LinuxC语言】信号的基本概念与基本使用

文章目录 前言一、信号的概念二、信号的使用2.1 基本的信号类型2.2 signal函数 总结 前言 在Linux环境下&#xff0c;信号是一种用于通知进程发生了某种事件的机制。这些事件可能是由操作系统、其他进程或进程本身触发的。对于C语言编程者来说&#xff0c;理解信号的基本概念和…

使用 ORPO 微调 Llama 3

原文地址&#xff1a;https://towardsdatascience.com/fine-tune-llama-3-with-orpo-56cfab2f9ada 更便宜、更快的统一微调技术 2024 年 4 月 19 日 ORPO 是一种新的令人兴奋的微调技术&#xff0c;它将传统的监督微调和偏好校准阶段合并为一个过程。这减少了训练所需的计算…

8.MyBatis 操作数据库(进阶)

文章目录 1.动态SQL插入1.1使用注解方式插入数据1.2使用xml方式插入数据1.3何时用注解何时用xml&#xff1f;1.4使用SQL查询中有多个and时&#xff0c;如何自动去除多余and1.4.1方法一&#xff1a;删除and之后的代码如图所示&#xff0c;再次运行1.4.2方法二&#xff1a;加上tr…

C语言——文件相关操作

2.什么是文件 3.文件的打开和关闭 4.文件的顺序读写 5.文件的随机读写 6.文本文件和二进制文件 7.文件读取结束的判定 8.文件缓冲区 一、文件相关介绍 1、为什么使用文件 文件用于永久存储数据。通过使用文件&#xff0c;我们可以在程序关闭后保存数据&#xff0c;以便将来…

Springboot图片上传【本地+oss】

文章目录 1 前端组件页面2 本地上传3 上传到阿里云oss3.1申请开通账号&#xff0c;做好先导准备3.2 开始使用 1 前端组件页面 使用的VueElement组件 在线cdn引入&#xff1a; <script src"https://cdn.bootcdn.net/ajax/libs/vue/2.7.16/vue.js"></script&…

Simulink|【免费】虚拟同步发电机(VSG)惯量阻尼自适应控制仿真模型

目录 主要内容 仿真模型要点 2.1 整体仿真模型 2.2 电压电流双闭环模块 2.3 SVPWM调制策略 2.4 无功电压模块 2.5 自适应控制策略及算法 部分结果 下载链接 主要内容 该模型为simulink仿真模型&#xff0c;主要实现的内容如下&#xff1a; 随着风力发电、…

免费APP分发平台 - 一个指南和解析

数字化时代的APP分发平台 随着数字化进程的加速免费APP分发平台 - 一个指南和解析&#xff0c;移动应用&#xff08;APP&#xff09;市场正迅速扩大。在这个充满竞争的市场中免费APP分发平台 - 一个指南和解析&#xff0c;一个优秀的APP分发平台能够帮助开发者和商家更有效地触…

用keras识别狗狗

一、需求场景 从照片从识别出狗狗 from keras.applications.resnet50 import ResNet50 from keras.preprocessing import image from keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np# 加载预训练的ResNet50模型 model ResNet5…

网络知识点之—QoS

QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;指一个网络能够利用各种基础技术&#xff0c;为指定的网络通信提供更好的服务能力&#xff0c;是网络的一种安全机制&#xff0c; 是用来解决网络延迟和阻塞等问题的一种技术。QoS的保证对于容量有限的网络来…

【matlab基础知识】(三)二维曲线绘制plot

x[-pi:0.0001:pi]; 选择较小步距 ysin(tan(x))-tan(sin(x));plot(x,y) 条件和函数值做一个点乘 x[-2:0.02:2];y1.1*sign(x).*(abs(x)>1.1)x.*(abs(x)<1.1);plot(x,y) 颜色&#xff0c;线形&#xff0c;曲线上的标志 由于0.01cosx波动太小&#xff0c;所以plotyy绘制多…

C语言 | Leetcode C语言题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; int minPathSum(int** grid, int gridSize, int* gridColSize) {int rows gridSize, columns gridColSize[0];if (rows 0 || columns 0) {return 0;}int dp[rows][columns];dp[0][0] grid[0][0];for (int i 1; i < rows; i) {dp[i…

【吃透Java手写】- Spring(上)-启动-扫描-依赖注入-初始化-后置处理器

【吃透Java手写】Spring&#xff08;上&#xff09;启动-扫描-依赖注入-初始化-后置处理器 1 准备工作1.1 创建自己的Spring容器类1.2 创建自己的配置类 ComponentScan1.3 ComponentScan1.3.1 Retention1.3.2 Target 1.4 用户类UserService Component1.5 Component1.6 测试类 2…

STM32——WWDG(窗口看门狗)

技术笔记&#xff01; 1.WWDG&#xff08;窗口看门狗&#xff09;简介 本质&#xff1a;能产生系统复位信号和提前唤醒中断的计数器。 特性&#xff1a; 递减的计数器&#xff1b; 当递减计数器值从 0x40减到0x3F时复位&#xff08;即T6位跳变到0&#xff09;&#xff1b; …