【MySQL数据库】多表查询(笛卡尔积现象,联合查询、内连接、左外连接、右外连接、子查询)-通过练习快速掌握法

在DQL的基础查询中,我们已经学过了多表查询的一种:联合查询(union)。本文我们将系统的讲解多表查询。

笛卡尔积现象

首先,我们想要查询emp表和stu表两个表,按照我们之前的知识栈,我们直接使用:

select * from emp,stu;

当查询emp时:15条记录被查询

当查询stu时:5条记录被查询

但是让我们来观察结果:

哇,查询到了70条记录 。而且根据结果我们可以看出:左表emp的每条记录都会与右表stu的每条记录组成一条新的记录,也就是14*5=70条记录。这种现象非常符合离散数学中学到的笛卡尔积的结果,所以我们将这种现象称为笛卡尔积现象。

笛卡尔积(Cartesian Product):表示两个集合之间的所有可能的有序对的集合

笛卡尔积的性质包括:

  1. 笛卡尔积的结果是一个新集合。
  2. 如果 AA 和 BB 其中一个为空集,则结果也为空集。
  3. 笛卡尔积的顺序是重要的,即 A×B≠B×A。

我们如何实现15+4的结果呢?直接使用上面的select肯定是不行了。

那么,此时有一个叫联合查询的方式出现在脑海里:

联合查询

关键字:【union all】

select empno,ename,job from emp
union all
select id,nick,pwd from stu;

观察结果:19=15+4条记录 (使用union代替union all可以实现去重的功能)

但是为了将记录查询出来,我们 必须合适选择每个表的字段,将两个表查询的字段的数据类型一一对应。empno int = id int,ename varchar = nick varchar ......

如果数据类型对应不上,那么将无法查询,结果是:

直接查询的条件限制法

那么联合查询也不能符合我们对查询结果的预期,这时候需要我们转换思路。从笛卡尔积现象开始:【需求:查询员工表以及每个员工对应的部门信息】

首先直接查询:

对于查询的结果,虽然有重复, 但至少有我们需要的结果,那么只需要将这个表中的有效记录提取出来,就可以了。也就是使用where条件进行限定:

此时我们查询的结果就符合我们的预期了。但注意,这时候我们操作时必须给每个字段指定上是哪个表的字段,不然的话,该字段属于二义性字段,无法通过语法分析,也就不能执行了。

内连接

select field from tb1 
[inner] join tb2 on condition;

等值连接

eg.根据一个编号查另一个表中改编号对应的内容。常见于:根据子表外键连接父表主键

【练习:查询员工表以及每个员工对应的部门信息】

select * from emp [inner]join dept on emp.DEPTNO = dept.DEPTNO;

非等值连接

eg.根据一个表的某个字段,查另一个表中该字段属于哪段区间的信息。实际用途:等级划分

【练习:根据员工的薪水查出薪水的等级】

自连接

eg.自连接是某个表的某个字段信息存储的数据是本表的另一条记录的信息。常用于:事物关联

【练习:根据员工表的领导编号查询领导的名字】

自连接的流程:为显示的字段起别名(避免两个结果字段名冲突,非必须)=》from选择查询表=》join 连接表(本表),并起别名(避免二义性,必须)=》连接条件。[过程中的每个字段都需要明确指出是哪个表] 

外连接

由于内连接会将连接条件的字段中空值的记录给过滤掉,所以为了显示较为全面的记录,我们采用外连接的方式进行多表查询。

左外连接

左外连接就是(left [outer] join ... on...)。显示主表的所有字段,并将被连接的从表符合连接条件的记录连接到主表,如果没有,主表显示原本记录,从表的字段中为空。

【练习:查询员工表以及每个员工对应的部门信息---显示所有员工】

右外连接

右外连接就是(right [outer] join ... on...)。与左外连接类似。

【练习:查询员工表以及每个员工对应的部门信息---显示所有部门】

我们对比发现,右外连接显示的记录比左外连接的记录多一条,多出的一条是部门表中的数据,但该部门在员工表中没有员工,所以全部显示为空。

:外连接查询的结果记录数 >= 内连接查询到的结果记录数

左外连接【左图】、右外连接【右图】

子查询

子查询:嵌套在其它SQL语句内的查询语句,且必须出现在圆括号内(查询一般是指select语句):子查询的结果可以作为外层查询的过滤条件或计算字段。

标量子查询

子查询返回结果是单个值,如数字、字符串、日期等最简单的形式。这种子查询称为标量子查询。【常用的操作符:| = | <> | > | >= | < | <= |】

【练习:查询销售部的部门员工信息】

第一步:查询销售部的部门编号

select deptno from dept where dname="SALES";

第二步:查询部门编号为上述结果的员工

select * from emp where deptno = 上条语句的结果;

第三步:合并一条语句:

select * from emp where deptno = (select deptno from dept where dname="SALES");

标量子查询可以在子句中使用聚合函数、而且子句的位置还可以出现在select后作为字段出现:

【练习:查询部门名,以及每个部门的人数】

select dname, (select count(*) from emp where dept.deptno=emp.deptno) emps 
from dept;

列子查询

子查询的结果是一列(或者多列),这种子查询称为列子查询

【常用操作符:in、not in、any、some、all】

IN:在指定的集合范围之内,多选一

NOT IN:不再指定的集合范围之内

ANY:子查询返回列表中,有任意一个满足即可【相当于集合所有元素作 or 运算】

SOME:与ANY相同,SOME与ANY等价

ALL:子查询返回列表的所有值都要满足【相当于集合所有元素之间作 and 运算】

【练习:查询销售部(SALES)和调研部(RESEARCH)所有员工信息】

select * 
from emp 
where deptno in (select deptno from dept where dname in ("SALES","RESEARCH"));-- or:
select * 
from emp 
where deptno in (select deptno from dept where dname="SALES" or dname="RESEARCH");

【练习:查询比销售部的所有人的工资都高的员工信息】

比所有人都高,也就是sal > all( {...} )

通过这个练习,我们不仅练习了all运算,我们还知道了,子句可以嵌套子句。

行子查询

子查询的返回结果是一行(可以是多行),这种子查询称为行子查询

【常用操作符:| = | <> | in | not in】

【练习:查询与“SMITH”的 薪资以及直属领导 都相同的员工信息】

-- (单行结果)
select * from emp where (sal,mgr) = (select sal,mgr from emp where ename = "SMITH");-- (多行结果)
select * from emp where (sal,mgr) in (select sal,mgr from emp where ename = "SMITH");

通过该练习,我们掌握了新的知识:

(field1,field2,...,fieldn) 可以通过加圆括号的方式直接与行结果进行运算【= | <> | in | not in】 

表子查询

子查询的结果可以是多行多列,产生这种结果的子查询称为表子查询。【常用操作符:IN】

这种就是行子查询的 in 操作。

-- (多行结果)
select * from emp where (sal,mgr) in (select sal,mgr from emp where ename = "SMITH");

感谢大家!欢迎指导、询问、探讨知识!

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

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

相关文章

网易云信架构升级实践,故障恢复时间缩至8秒

一、项目背景 网易云信是网易旗下集IM与音视频技术于一体的PaaS服务平台&#xff0c;为全球提供融合通信与视频的核心功能和组件&#xff0c;包括IM即时通讯、短信、信令等通信服务&#xff0c;以及RTC、直播、点播、互动直播、互动白板等音视频服务&#xff0c;此外&#xf…

[HelloCTF]PHPinclude-labs超详细WP-Level 1-FILE协议

源码分析 <?php include("get_flag.php");isset($_GET[wrappers]) ? include("file://".$_GET[wrappers]) : ;highlight_file(__FILE__); ?>第一句 include("get_flag.php");, 使代码包含了 get_flag.php 的内容 大概是生成 Flag 之类的…

MongoDB 可观测性最佳实践

MongoDB 介绍 MongoDB 是一个高性能、开源的 NoSQL 数据库&#xff0c;它采用灵活的文档数据模型&#xff0c;非常适合处理大规模的分布式数据。MongoDB 的文档存储方式使得数据结构可以随需求变化而变化&#xff0c;提供了极高的灵活性。它支持丰富的查询语言&#xff0c;允许…

4.angular 服务

服务是在controller里面引入的服务&#xff1a; 最好是内部服务在前面&#xff0c;自定义服务在后面 内部服务 $scope $scope.$watch(‘属性名’, function(newVal, oldVal) {}, true) true是深度监听,对象函数等$scope.$apply 触发页面更新,里面传入回调函数,比如说之前那个…

HarmonyOS NEXT开发进阶(十二):build-profile.json5 文件解析

文章目录 一、前言二、Hvigor脚本文件三、任务与任务依赖图四、多模块管理4.1 静态配置模块 五、分模块编译六、配置多目标产物七、配置APP多目标构建产物八、定义 product 中包含的 target九、拓展阅读 一、前言 编译构建工具DevEco Hvigor&#xff08;以下简称Hvigor&#x…

【强化学习基石】Deepseek V3技术报告中的GRPO算法是什么?

1. Deepseek V3技术报告中的GRPO算法是什么? GRPO(Generalized Relative Policy Optimization)是一种在强化学习领域用于策略优化的算法。它主要是在策略梯度方法的基础上进行改进,目的是更有效地优化策略网络,从而提高智能体在环境中的表现。 GRPO 的核心思想是通过相对…

VSCode C/C++ 开发环境完整配置及常见问题(自用)

这里主要记录了一些与配置相关的内容。由于网上教程众多&#xff0c;部分解决方法并不能完全契合我遇到的问题&#xff0c;因此我选择以自己偏好的方式&#xff0c;对 VSCode 进行完整的配置&#xff0c;并记录在使用过程中遇到的问题及解决方案。后续内容也会持续更新和完善。…

Billu_b0x靶机攻略

1&#xff0c;安装好靶机并打开&#xff0c;打开kali进行扫描得到靶机ip为192.168.50.138 2&#xff0c;访问靶机以及扫描出的目录 3&#xff0c;访问test.php发现file参数为空&#xff0c;尝试拼接其他路径来访问&#xff0c;发现可以file传参&#xff0c;利用插件进行post传参…

如何搭建一个安全经济适用的TRS交易平台?

TRS&#xff08;总收益互换&#xff09;一种多方参与的投资方式&#xff0c;也是绝对收益互换&#xff08;total return swap&#xff09;的一种形式。 它是一种衍生合约&#xff0c;是一种金融衍生品的合约&#xff0c;是指交易双方在协议期间将参照资产的总收益转移给信用保…

LeetCode 解题思路 16(Hot 100)

解题思路&#xff1a; 初始化辅助节点&#xff1a; dummy&#xff1a;哑节点。pre&#xff1a;当前链表的前一个节点。start&#xff1a;当前链表的第一个节点。end&#xff1a;当前链表的最后一个节点。nextStart&#xff1a;end.next&#xff0c;下组链表的第一个节点&…

数据结构——串、数组和广义表

串、数组和广义表 1. 串 1.1 串的定义 串(string)是由零个或多个字符组成的有限序列。一般记为 S a 1 a 2 . . . a n ( n ≥ 0 ) Sa_1a_2...a_n(n\geq0) Sa1​a2​...an​(n≥0) 其中&#xff0c;S是串名&#xff0c;单引号括起来的字符序列是串的值&#xff0c; a i a_i a…

LeetCode BFS层序遍历树

中等 103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#…

深度学习大模型补充知识点

文章目录 VIT用途处理方法与CNN区别 多模态LLM&#xff1a;大语言模型预训练指令微调强化学习 总结 VIT ViT&#xff08;Vision Transformer&#xff09; 首次将 Transformer架构成功应用于计算机视觉领域&#xff08;尤其是图像分类任务&#xff09;。传统视觉任务主要依赖卷…

RCore学习记录002

初次运行RCore和调试&#xff0c;这里使用的RCore代码是实验指导书的代码&#xff0c;而非RCore训练营的 讲两种方法&#xff0c;第一种是传统的gdb调试&#xff0c;在上一节中提到的riscv交叉编译工具链中的已经安装了riscv的gdb&#xff0c;另一种是基于CLion的可视化调试&a…

maven在idea上搭建

maven搭建 首先进入maven官网&#xff0c;去download下载欢迎使用 Apache Maven – Maven下载免安装版本&#xff0c;解压在任意目录下&#xff0c;命名别取中文名 配置环境变量 复制你刚刚maven解压的路径&#xff0c;我这里是D:\resource\apache-maven-3.8.8&#xff0c;之…

【sql靶场】第18-22关-htpp头部注入保姆级教程

目录 【sql靶场】第18-22关-htpp头部注入保姆级教程 1.回顾知识 1.http头部 2.报错注入 2.第十八关 1.尝试 2.爆出数据库名 3.爆出表名 4.爆出字段 5.爆出账号密码 3.第十九关 4.第二十关 5.第二十一关 6.第二十二关 【sql靶场】第18-22关-htpp头部注入保姆级教程…

K8S下nodelocaldns crash问题导致域名请求响应缓慢

前言 最近做项目&#xff0c;有业务出现偶发的部署导致响应很慢的情况&#xff0c;据了解&#xff0c;业务使用域名访问&#xff0c;相同的nginx代理&#xff0c;唯一的区别就是K8S重新部署了。那么问题大概率出现在容器平台&#xff0c;毕竟业务是重启几次正常&#xff0c;偶…

SpringBoot之如何集成SpringDoc最详细文档

文章目录 一、概念解释1、OpenAPI2、Swagger3、Springfox4、Springdoc5. 关系与区别 二、SpringDoc基本使用1、导包2、正常编写代码&#xff0c;不需要任何注解3、运行后访问下面的链接即可 三、SpringDoc进阶使用1、配置文档信息2、配置文档分组3、springdoc的配置参数**1. 基…

基于扣子(coze.cn)搭建一个古文化学习助手

highlight: a11y-dark 扣子Coze 是由字节跳动推出的一个AI聊天机器人和应用程序编辑开发平台&#xff0c;可以理解为字节跳动版的GPTs。 下面进行Coze的登录&#xff0c;初步使用&#xff0c;创建定制化的Bot&#xff08;聊天机器人&#xff09;&#xff0c;插件使用等操作。…

Modbus TCP到RTU:轻松转换指南!

Modbus TCP 到 RTU&#xff1a;轻松转换指南&#xff01; 在现代工业自动化领域&#xff0c;Modbus TCP和Modbus RTU两种通信协议因其高效、稳定的特点被广泛应用。然而&#xff0c;随着技术的发展和设备升级的需求&#xff0c;经常会遇到需要将这两种协议进行互相转换的场景。…