数据库关系运算之连接

在数据库理论中,关系连接(Join) 是将两个或多个关系(表)中的元组(行)根据一定条件组合成新关系的操作,是关系型数据库中核心且高频使用的操作。其本质是通过共享的属性(列)建立表之间的关联,从而获取更完整的信息。

一、连接的核心要素

  1. 参与连接的表:至少两个表(如表A和表B)。
  2. 连接条件:指定表之间的关联规则,通常基于两表中相同或可比较的列(如A.id = B.a_id)。
  3. 连接结果:新表,包含满足条件的元组组合,列通常是两表列的并集(可通过选择指定需要的列)。

二、常见连接类型及示例

为便于理解,先定义两个示例表:

表1:学生表(Student)
学号(S_id)姓名(S_name)班级(Class)
101张三一班
102李四二班
103王五一班
104赵六三班
表2:成绩表(Score)
成绩ID(Sc_id)学号(S_id)科目(Subject)分数(Score)
1101数学90
2101语文85
3102数学88
4103英语92
5105数学75
1. 内连接(Inner Join)
  • 定义:只保留两个表中同时满足连接条件的元组。
  • 逻辑:结果 = 表A中满足条件的元组 + 表B中对应满足条件的元组(交集)。
  • 示例需求:查询“有成绩记录的学生姓名及对应成绩”(即学生表和成绩表中都存在的学号)。
-- SQL语句
SELECT s.S_name, s.S_id, sc.Subject, sc.Score
FROM Student s
INNER JOIN Score sc ON s.S_id = sc.S_id;
  • 结果
    | S_name | S_id | Subject | Score |
    |--------|------|---------|-------|
    | 张三 | 101 | 数学 | 90 |
    | 张三 | 101 | 语文 | 85 |
    | 李四 | 102 | 数学 | 88 |
    | 王五 | 103 | 英语 | 92 |

  • 说明

    • 赵六(104)在成绩表中无记录,故未出现;
    • 成绩表中105号学生不在学生表中,故未出现;
    • 张三(101)有两条成绩记录,因此结果中会对应两条行(一行数学、一行语文)。
2. 左连接(Left Join / Left Outer Join)
  • 定义:以左表(左侧的表)为基准,保留左表所有元组,右表中满足条件的元组与之匹配;若右表无匹配,右表列显示为NULL。
  • 逻辑:结果 = 左表所有元组 + 右表中对应满足条件的元组(左表全集 + 交集)。
  • 示例需求:查询“所有学生的姓名及成绩(无成绩的学生显示‘无成绩’)”。
-- SQL语句
SELECT s.S_name, s.S_id, IFNULL(sc.Subject, '无科目') AS Subject,  -- 用IFNULL处理NULLIFNULL(sc.Score, '无成绩') AS Score
FROM Student s
LEFT JOIN Score sc ON s.S_id = sc.S_id;
  • 结果
    | S_name | S_id | Subject | Score |
    |--------|------|----------|--------|
    | 张三 | 101 | 数学 | 90 |
    | 张三 | 101 | 语文 | 85 |
    | 李四 | 102 | 数学 | 88 |
    | 王五 | 103 | 英语 | 92 |
    | 赵六 | 104 | 无科目 | 无成绩 | (赵六在成绩表中无记录,右表列用NULL填充后替换)

  • 说明:左表(Student)的所有4名学生均保留,赵六因无成绩记录,成绩表相关列显示为“无科目”和“无成绩”。

3. 右连接(Right Join / Right Outer Join)
  • 定义:以右表(右侧的表)为基准,保留右表所有元组,左表中满足条件的元组与之匹配;若左表无匹配,左表列显示为NULL。
  • 逻辑:结果 = 右表所有元组 + 左表中对应满足条件的元组(右表全集 + 交集)。
  • 示例需求:查询“所有成绩记录对应的学生姓名(包括无对应学生的成绩)”。
-- SQL语句
SELECT IFNULL(s.S_name, '未知学生') AS S_name, sc.S_id, sc.Subject, sc.Score
FROM Student s
RIGHT JOIN Score sc ON s.S_id = sc.S_id;
  • 结果
    | S_name | S_id | Subject | Score |
    |----------|------|---------|-------|
    | 张三 | 101 | 数学 | 90 |
    | 张三 | 101 | 语文 | 85 |
    | 李四 | 102 | 数学 | 88 |
    | 王五 | 103 | 英语 | 92 |
    | 未知学生 | 105 | 数学 | 75 | (105号学生不在Student表中,左表列用NULL填充后替换)

  • 说明:右表(Score)的所有5条成绩记录均保留,105号学生因不在学生表中,姓名显示为“未知学生”。

4. 全连接(Full Join / Full Outer Join)
  • 定义:保留两个表中所有元组,满足条件的元组正常匹配;不满足条件的元组,对应另一表的列显示为NULL。
  • 逻辑:结果 = 左表全集 + 右表全集(并集)。
  • 注意:MySQL不直接支持Full Join,可通过“Left Join + Union + Right Join”模拟。

示例结果(模拟)

S_nameS_idSubjectScore
张三101数学90
张三101语文85
李四102数学88
王五103英语92
赵六104无科目无成绩
未知学生105数学75
5. 交叉连接(Cross Join)
  • 定义:不指定连接条件时的连接,返回两个表的笛卡尔积(左表每一行与右表每一行都组合)。
  • 特点:结果行数 = 左表行数 × 右表行数(通常需配合条件过滤,否则结果冗余)。
  • 示例:Student(4行)× Score(5行)= 20行结果(此处省略冗余内容)。

三、连接的使用场景总结

连接类型核心用途典型场景示例
内连接获取两表关联的“有效数据”学生成绩查询(必须有学生和成绩记录)
左连接以左表为基准,补充右表信息(允许右表为空)员工及所属部门查询(含暂无部门的员工)
右连接以右表为基准,补充左表信息(允许左表为空)订单及客户信息查询(含暂无客户的订单)
全连接获取两表所有数据及关联数据合并两个来源的用户数据(含独有和共有)
交叉连接生成所有可能组合(需配合条件)生成“学生-课程”所有可选组合

通过以上示例可以看出,连接的核心是通过“共享列”建立表之间的关联,不同连接类型决定了结果中保留的数据范围。实际使用时,需根据业务需求选择合适的连接类型,并注意连接条件的准确性(避免笛卡尔积或遗漏数据)。

在数据库关系连接中,不同的连接类型适用于不同的业务场景。以下通过**“电商订单系统”**的典型场景,举例说明常用连接类型的实际应用(假设存在两张核心表:订单表(orders)用户表(users))。

基础表结构与数据

为了更直观理解,先定义两张表的结构和示例数据:

1. 用户表(users)

存储用户的基础信息,主键为user_id

user_id(主键)usernameage
101张三25
102李四30
103王五28
104赵六35
2. 订单表(orders)

存储用户的订单信息,user_id为外键(关联users表的user_id),主键为order_id

order_id(主键)user_id(外键)order_timetotal_amount
10011012025-07-01 10:00299
10021012025-07-05 14:30599
10031022025-07-03 09:15199
10041052025-07-06 16:40899

典型场景与连接类型示例

场景1:查询“有订单的用户及其订单信息”(内连接 Inner Join)

业务需求:运营需要统计“已下单用户”的订单明细(不含未下单用户,也不含无对应用户的异常订单)。

原理:内连接只保留两张表中“连接条件匹配”的记录(即users.user_id = orders.user_id且两边都存在的记录)。

SQL语句

SELECT u.user_id, u.username, o.order_id, o.total_amount
FROM users u
INNER JOIN orders o 
ON u.user_id = o.user_id;

查询结果(只保留匹配的记录):

user_idusernameorder_idtotal_amount
101张三1001299
101张三1002599
102李四1003199

说明

  • 王五(103)、赵六(104)因无订单,未出现在结果中;
  • 订单1004(user_id=105)因无对应用户,也未出现在结果中。
场景2:查询“所有用户的订单情况(含未下单用户)”(左连接 Left Join)

业务需求:客服需要整理“所有用户的订单记录”,包括“未下单用户”(需标记为“无订单”)。

原理:左连接以“左表(users)”为基准,保留左表所有记录;右表(orders)中匹配的记录正常显示,不匹配的记录用NULL填充。

SQL语句

SELECT u.user_id, u.username, o.order_id, IFNULL(o.total_amount, '无订单') AS total_amount
FROM users u
LEFT JOIN orders o 
ON u.user_id = o.user_id;

查询结果(保留所有用户,无订单的用户订单字段为NULL或“无订单”):

user_idusernameorder_idtotal_amount
101张三1001299
101张三1002599
102李四1003199
103王五NULL无订单
104赵六NULL无订单

说明

  • 左表(users)的所有用户(101-104)均被保留;
  • 王五(103)、赵六(104)无订单,订单相关字段显示为NULL(通过IFNULL转换为“无订单”)。
场景3:查询“所有订单及对应用户(含异常订单)”(右连接 Right Join)

业务需求:技术人员需要排查“异常订单”(即订单对应的用户不存在的情况)。

原理:右连接以“右表(orders)”为基准,保留右表所有记录;左表(users)中匹配的记录正常显示,不匹配的记录用NULL填充。

SQL语句

SELECT o.order_id, o.user_id, u.username, IF(u.user_id IS NULL, '异常订单', '正常订单') AS order_status
FROM users u
RIGHT JOIN orders o 
ON u.user_id = o.user_id;

查询结果(保留所有订单,无对应用户的订单标记为异常):

order_iduser_idusernameorder_status
1001101张三正常订单
1002101张三正常订单
1003102李四正常订单
1004105NULL异常订单

说明

  • 右表(orders)的所有订单(1001-1004)均被保留;
  • 订单1004(user_id=105)无对应用户,用户相关字段(username)显示为NULL,被标记为“异常订单”。
场景4:查询“所有用户和所有订单(含未匹配记录)”(全连接 Full Join)

业务需求:数据分析师需要一次性获取“所有用户+所有订单”的完整数据(含未下单用户和异常订单),用于全局统计。

原理:全连接保留左表和右表的所有记录,双方不匹配的部分用NULL填充(注:MySQL不直接支持FULL JOIN,可通过LEFT JOIN + UNION + RIGHT JOIN模拟)。

模拟SQL语句

-- 左连接结果(所有用户+匹配订单)
SELECT u.user_id, u.username, o.order_id, o.total_amount
FROM users u LEFT JOIN orders o ON u.user_id = o.user_id
UNION  -- 合并结果并去重
-- 右连接中“订单无对应用户”的部分(避免重复)
SELECT u.user_id, u.username, o.order_id, o.total_amount
FROM users u RIGHT JOIN orders o ON u.user_id = o.user_id
WHERE u.user_id IS NULL;

查询结果(所有用户+所有订单,不匹配部分为NULL):

user_idusernameorder_idtotal_amount
101张三1001299
101张三1002599
102李四1003199
103王五NULLNULL
104赵六NULLNULL
NULLNULL1004899

总结:连接类型与场景对应关系

连接类型核心作用典型场景
内连接(Inner)只保留匹配的记录正常业务数据查询(如已下单用户的订单明细)
左连接(Left)保留左表所有记录,匹配右表数据需包含“主表全部数据”的查询(如所有用户的订单情况)
右连接(Right)保留右表所有记录,匹配左表数据需包含“从表全部数据”的查询(如所有订单及用户匹配情况)
全连接(Full)保留左右表所有记录全局数据统计(如所有用户+所有订单的完整视图)

通过这些场景可以看出,连接的核心是“基于关联字段(如user_id)匹配数据”,而选择哪种连接类型,取决于业务是否需要保留“未匹配的记录”。

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

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

相关文章

npm全局安装后,依然不是内部或外部命令,也不是可运行的程序或批处理文件

虽然通过 npm install -g yarn 安装了 Yarn,但系统无法识别 yarn 命令。这通常是因为 npm 的全局安装目录没有添加到系统的 PATH 环境变量中C:\Users\Administrator>npm install -g yarnadded 1 package in 518msC:\Users\Administrator>yarn yarn 不是内部或…

C++ Proactor 与 Reactor 网络编程模式

🧠 C Proactor 与 Reactor 网络编程模式📌 核心区别概述特性Reactor 模式Proactor 模式事件驱动核心监听 I/O 就绪事件 (可读/可写)监听 I/O 完成事件 (读完成/写完成)I/O 执行者用户线程 主动执行 I/O 操作操作系统 异步执行 I/O 操作控制流同步非阻塞 …

从手动操作到自动化:火语言 RPA 在多系统协作中的实践

在企业日常运营中,很多业务流程需要在多个系统间来回切换:从 A 系统导出数据,到 B 系统校验格式,再到 C 系统录入信息…… 这些跨系统操作步骤繁琐、逻辑固定,却往往依赖人工完成,不仅效率低下,…

Spring Security 实践之登录

前言Spring Security是一个功能强大且高度且可定制的身份验证和访问控制框架,包含标准的身份认证和授权。 本文主要介绍SpringBoot中如何配置使用 Spring Security 安全认证框架并简述相关原理和步骤。核心认证流程解析请求过滤 用户提交登录表单AbstractAuthentica…

华为云开发者空间 × DeepSeek-R1 智能融合测评:云端开发与AI客服的协同进化

前言: 华为开发者空间,是为全球开发者打造的专属开发者空间,致力于为每位开发者提供一台云主机、一套开发工具和云上存储空间,当普惠云资源遇见推理大模型,企业服务与开发效能的范式革命正在加速。华为云开发者空间&am…

二分查找----4.搜索旋转排序数组

题目链接 /** 升序数组在某个位置被分割为前后两部分,前后两部分整体互换;在被改变后的数组中找到目标值 O(log n)---> 二分查找 特点: 旋转后的数组被分割为两个独立的递增区间 左半区的最小值,大于右半区的最大值(mid所在区间的判断依据) 二分策略: 首先判断mid落在左区间…

地球表面附近两点之间距离、高低角和方位角的计算方法,VC++代码实操!

书接上文,这篇文章介绍具体的VC编程实现,代码实操。任何一个算法,你必须将其编写为代码,运行结果正确,才算真正掌握了,否则都是似懂非懂,一知半解,下面先给出仿真结果的截图&#xf…

uniapp各大平台导航组件

最近有个需求要点击导航然后跳出各家导航软件话不多出直接贴出代码&#xff1a;这个可以作为组件引入<template><view><view class"nav" :style"{color: customColor}" click.stop"openMap">{{title}}</view><!-- 弹…

Access开发一键删除Excel指定工作表

Hi&#xff0c;大家好&#xff01;又到了每周给大家更新的时间了&#xff0c;这周给大家讲讲excel的处理操作吧。在开始前&#xff0c;先给大家汇报一下我们框架的进度&#xff0c;最近两周没有直播&#xff0c;所以大家不太清楚目前的进度&#xff0c;框架目前就差权限了&…

无广告终端安全产品推荐:打造纯净办公环境的安全之选

在数字化办公时代&#xff0c;终端安全防护是企业和个人不可忽视的重要环节。然而&#xff0c;许多传统安全软件往往伴随着频繁的广告弹窗和推广信息&#xff0c;不仅干扰正常工作&#xff0c;还可能成为潜在的安全隐患。本文将为您介绍几款「无广告、无捆绑」的终端产品&#…

使用UE5自带节点InteriorCubemap制作假室内效果

Interior Mapping&#xff08;室内映射&#xff09;是一种用着色器方法模拟室内结构纹理的方式&#xff0c;避免了真实对室内场景建模造成的模型面数渲染开销&#xff0c;在《蜘蛛侠》《城市天际线》等游戏中都采用了该技术。 UE自带了节点InteriorCubemap&#xff08;Unity S…

基于单片机睡眠质量/睡眠枕头设计

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目速选一览表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目功能速览 概述 随着现代社会生活节奏的加快&#xff0c;睡眠质量问题日益受到人们的关注。本研究设计了一种基于…

Ajax第一天

AJAX概念&#xff1a;AJAX 是浏览器与服务器进行数据通信的技术&#xff08;把数据变活&#xff09;语法&#xff1a;1.引入 axios.js&#xff1a;https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js2.使用 axios 函数✓ 传入配置对象✓ 再用 .then 回调函数接收结果&#…

AI大模型各类概念扫盲

以下内容整理自AI&#xff0c;进行一个概念扫盲&#xff1a;Prompt&#xff08;提示词&#xff09; Prompt是用户提供给AI模型的指令或问题&#xff0c;用于引导模型生成特定输出。良好的Prompt设计能显著提升模型的任务理解能力和响应质量&#xff0c;例如通过结构化提示&…

Linux系统编程——网络

一、TCP/UDP 1、osi模型 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层&#xff08;下层为上层提供服务&#xff09; 2、TCP/IP模型&#xff08;TCP/IP协议栈&#xff09; 应用层&#xff1a; HTTP&#xff08;超文本传输协议&#xff09;、FTP&#xff08;文件…

taro+pinia+小程序存储配置持久化

主要通过taro的getStorageSync,setStorageSync实现配置持久化 // https://pinia.esm.dev/introduction.html import { defineStore } from pinia; import { CreditCardDateUtils } from /untils/compute; import { getStorageSync, setStorageSync } from "tarojs/taro&qu…

抖音小游戏好做吗?

从0到1&#xff0c;教你打造爆款抖音小游戏随着移动互联网的发展&#xff0c;抖音小游戏凭借便捷即玩、流量庞大等优势&#xff0c;成为游戏开发者的热门选择。想知道如何开发出一款吸睛又好玩的抖音小游戏吗&#xff1f;下面就为你详细介绍开发流程。一、前期规划明确游戏类型…

Spring Boot 3核心技术面试指南:从迁移升级到云原生实战,9轮技术攻防(含架构解析)

面试官&#xff1a;cc程序员&#xff0c;聊聊Spring Boot 3的那些事儿&#xff1f; 场景背景 互联网大厂云原生架构部面试官老王&#xff0c;与自称"Spring Boot骨灰粉"的cc程序员展开技术对决。 面试过程 第一轮&#xff1a;迁移升级 面试官&#xff1a;Spring Boot…

技术演进中的开发沉思-42 MFC系列:Components 与 ActiveX Controls

点击程序启动时&#xff0c;是不是看过有加载的画面。在VC开发时&#xff0c;可使用 VC 的 Component Gallery&#xff0c;找到 Splash screen 组件&#xff0c;当时觉得组件就是给程序员的暖手宝。一、Component GalleryComponent Gallery 在 VC 里的位置很特别 —— 它藏在 “…

抽象类、接口、枚举

第八天&#xff08;坚持&#xff09;抽象类1.什么是抽象类&#xff0c;作用特点。抽象类是面向对象编程中一种特殊的类&#xff0c;它不能被实例化&#xff0c;主要用于作为其他类的基类&#xff08;父类&#xff09;。抽象类的主要作用是定义公共结构和行为规范&#xff0c;同…