学SQL JOINS看这一篇文章就够了

目录

下面以实例进行分析

内连接

inner join 或者join(等同于inner join)

外连接

left join 或者left outer join(等同于left join)

[ left join 或者left outer join(等同于left join) ] + [ where B.column is null ]

right join 或者right outer join(等同于right join)

[ right join 或者right outer join(等同于right join) ] + [ where A.column is null ]

full join (mysql不支持,但是可以用 left join union right join代替)

full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+is null代替)

交叉连接

cross join

cross join + where

注意事项

问题分析

EXPLAIN扫描行数不同

SQL JOINS执行顺序


在数据库中,连接(Join)是用于将两个或多个表中的数据关联起来的操作。连接操作有多种类型,其中包括内连接和外连接。内连接的话只有一种而外连接的话有六种,当然还有一种连接叫做交叉连接。

  • 内连接:join , inner join
  • 外连接:left join , left outer join , right join , right outer join , union
  • 交叉连接:cross join

下面以实例进行分析

#首先创建两张表a和b
mysql> show create table a\G
*************************** 1. row ***************************Table: a
Create Table: CREATE TABLE `a` (`id` int NOT NULL,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.01 sec)mysql> show create table b\G
*************************** 1. row ***************************Table: b
Create Table: CREATE TABLE `b` (`id` int NOT NULL,`age` int DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.01 sec)

两张表格式如下:

内连接

inner join 或者join(等同于inner join)

语法:

select *  from a join b on a.id=b.id;
or
select *  from a inner join b on a.id=b.id;

结果:

应用场景:

这种场景下得到的是满足某一条件的A,B内部的数据;正因为得到的是内部共有数据,所以连接方式称为内连接。

外连接

left join 或者left outer join(等同于left join)

语法:

select * from a left join b on a.id=b.id;
or
select * from a left outer join b on a.id=b.id;

结果:

结果如下,TableA中B不存在的记录填充Null

应用场景:

这种场景下得到的是A的所有数据,和满足某一条件的B的数据。

[ left join 或者left outer join(等同于left join) ] + [ where B.column is null ]

语法:

select * from a left outer join b on a.id=b.id where b.id is not null;

结果:

left join表a的数据全部显示,匹配表b的数据也显示,而b.id再次过滤掉 表b的id为空的

应用场景:

这种场景下得到的是A中的所有数据减去"与B满足同一条件 的数据",然后得到的A剩余数据。

right join 或者right outer join(等同于right join)

语法:

select * from a right outer join b on a.id=b.id;
or
select * from a right outer join b on a.id=b.id;

结果:

TableB中A不存在的记录填充Null

应用场景:

这种场景下得到的是B的所有数据,和满足某一条件的A的数据。

[ right join 或者right outer join(等同于right join) ] + [ where A.column is null ]

语法:

select * from a right join b on a.id=b.id where a.id is not null;

结果:

应用场景:

这种场景下得到的是B中的所有数据减去 "与A满足同一条件 的数据“,然后得到的B剩余数据。

full join (mysql不支持,但是可以用 left join union right join代替)

语法:

 select * from a left join b on a.id=b.id union select * from a right join b on a.id=b.id;

结果:

union过后,重复的记录会合并(id为2,3,4的三条记录)

应用场景:

这种场景下得到的是满足某一条件的公共记录,和独有的记录。

full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+is null代替)

语法:

select * from a left join b on a.id=b.id where b.id is null union select * from a right join b on a.id=b.id where a.id is null;

结果:

应用场景:

交叉连接

cross join

语法:

 select * from a cross join b;

结果:

cross join + where

语法:

select * from a cross join b where a.id=b.id;

结果:

这种情况下实际上实现了内连接的效果

注意事项

  • 一般cross join后面加上where条件,但是用cross join+on也是被解释为cross join+where(显示连接);
  • 一般内连接都需要加上on限定条件,如果不加会被解释为交叉连接;
  • 如果连接表格使用的是逗号,会被解释为交叉连接(隐式连接)。

注:隐式连接(Implicit Join)会出现数据冗余和性能问题,主要是因为它使用逗号分隔表名的方式进行连接,而没有明确指定连接条件,这样就会导致以下两个问题:

  1. 数据冗余问题: 隐式连接会产生笛卡尔积,即将左表的每一行与右表的每一行进行组合,然后返回所有可能的组合结果,包括那些并不符合连接条件的组合。这就会导致结果集中出现多余的数据,从而产生数据冗余的问题。
  2. 性能问题: 隐式连接的查询效率很低,因为它会处理大量的无用数据,浪费了系统资源和时间。当表a和表b的记录数都很大时,隐式连接会产生庞大的临时表,消耗大量内存和CPU资源。此外,由于没有明确指定连接条件,数据库引擎会对每一个可能组合进行比较,这会进一步降低查询效率。

问题分析

EXPLAIN扫描行数不同

当我们使用explain执行计划,分析select * from a join b on a.id=b.id;语句时会发现两张表的数据基本相同,通过唯一主键索引关联,数据是一对一的,为什么扫描的行数不同。

语法:

explain select * from a join b on a.id=b.id;

结果:

分析:

sql join执行流程

  1. 从a表取出一行
  2. 从取出的这一行取出字段1,然后到表b中查找a.id=b.id
  3. 取出从表b中获取到的数据,跟从表a中的数据组成一行,作为结果集的一部分

explain执行计划的第一行,实际上就是表a的全表扫描,扫描行数比较大

执行计划的第二行,实际代表的是用表a去表b中查找数据,这里用到了索引,所以扫描行数是一行。

SQL JOINS执行顺序

  1. A left join B 返回 A 表数据,附带 B 表中符合条件的数据
  2. A left join B right join C
  3. A left join B 假设等于结果 AB
  4. AB left join C 返回 AB ,附带 C中符合条件的数据

  1. A left join B 返回 A 表数据,附带 B 表中符合条件的数据
  2. A left join B right join C
  3. A left join B 假设等于结果 AB
  4. AB right join C 返回 C ,附带 AB 中符合条件的数据

通过上述两个sql可以看到sql join的执行顺序

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

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

相关文章

Docker Registry本地镜像仓库部署并实现远程连接拉取镜像

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

Centos系列:shell编程综合练习(个人学习记录)

shell编程综合练习(个人学习记录) shell编程until 循环跳出循环1. break命令2. continue 命令 Shell函数特殊变量输入输出重定向输出重定向输入重定向重定向 Shell实战监控centos7运行状态/proc/stat文件编写脚本free命令监控系统内存 shell编程 until …

ubuntu几个版本开启或关闭图形界面小结

在下面几个系统做过验证: ubuntu-16.04.7-desktop-amd64(内核版本:Linux 4.15.0-112) ubuntu-18.04.6-desktop-amd64(内核版本:Linux 5.4.0-150) ubuntu-20.04.6-desktop-amd64(内…

h5网站开发-微信浏览器无法自动播放视频的解决方式?

一、需求: 使用h5开发的网站,首页的banner是一个video视频,在PC端上和手机浏览器上都能正常播放,但是在手机微信浏览器里面视频是无法自动播放的。 二、实现效果: 1.微信浏览器的效果: 2.正常效果&…

如何实现高效代码审查,赋能大规模开发

对于许多企业来说,代码审查都是开发过程中不可缺少的一环。软件开发人员通常会对代码审查感到又爱又恨。一般来说,实施代码审查的企业普遍认为通过及早发现问题和低效率,在长远来看可节省时间。 阅读本篇文章,您将了解到什么是代…

JS浮点数精度问题及解决方案

前端面试大全JS浮点数精度问题及解决方案 🌟经典真题 🌟浮点数精度常见问题 🌟为什么会有这样的问题 🌟真题解答 🌟总结 🌟经典真题 为什么 console.log(0.20.10.3) 得到的值为 false 🌟…

vs-code之vue3插件

1.Vue 3 Support - All In One Vue3 代码片段突出显示了 Visual Studio Code 的格式化程序生成器 生成vue3对应的的代码 如ref等, 2.Volar 相信使用 VSCode 开发 Vue2 的同学一定对 Vetur 插件不会陌生,作为 Vue2 配套的 VSCode 插件,它的主…

C++学习之路(十)C++ 用Qt5实现一个工具箱(增加一个时间戳转换功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《JSON数据格式化》功能,还是比较实用的。为了继续丰富我们的工具箱,今天我们就再增加一个平时经常用到的功能吧,就是「 时间戳转换 」功能,而且实现点击按钮后文字进行变…

Unity中C#如何访问并修改Shader材质

文章目录 前言一、我们用点击按钮来改变Shader传入的颜色值1、在渲染GUI时,绘制一个按钮2、我们使用一个公共的成员变量存储需要进行修改的游戏对象3、最后给绘制的按钮点击增加逻辑即可 二、测试使用的代码1、Shader代码:2、C#脚本 前言 我们写好Shade…

电源自动测试系统| 电源模块温度循环怎么测试?

在一些应用领域,电源模块会在极端环境温度条件下工作。为了确保电源在高低温环境下可以正常运行,满足设备需求,需要对电源模块进行温度循环测试。 温度循环测试是指电源模块经过升温、保温、降温等多次循环试验来检测其在温度变化下的耐热性、…

关于自动化测试框架pytest的Fixture固件

什么是固件 Fixture 翻译成中文即是固件的意思。它其实就是一些函数,会在执行测试方法/测试函数之前(或之后)加载运行它们,常见的如接口用例在请求接口前数据库的初始连接,和请求之后关闭数据库的操作。 我们之前在A…

Hana Studio打开BW失败

Hana Studio打开BW失败 JCo initialization failed with java.lang.UnsatisfiedLinkError: D:\ycy\BW培训\HANA\configuration\org.eclipse.osgi\357\0.cp\lib\sapjco3.dll: Can’t find dependent libraries 这个提示应该是VC版本问题,按如下链接中的地址下载安装…

使用SD-WAN新方式,解锁分公司访问总部私有云

某企业是一家跨地区运营的大型企业,总部位于上海,拥有多个分公司遍布全国。其中北京分公司作为该企业在北方地区的重要分支机构,负责着该地区的市场开拓和业务发展。 为了实现分公司与总部之间的有效沟通和信息共享,北京分公司使用…

Linux快速配置拨号

在Linux上进行ADSL拨号配置,通常需要使用pppoeconf命令进行设置。pppoeconf是一个用于配置pppoe连接的工具,它可以帮助用户快速设置pppoe连接并生成配置文件。下面是一个详细的步骤指南,以帮助您在Linux上进行ADSL拨号配置。 步骤1&#xff…

ToDesk优惠码来了,需要的不容错过

最近发现Todesk也有活动了,很多小伙伴不知道,除了中秋国庆双节,ToDesk另有专享优惠码,输入优惠码最高立减25元,即使是活动日也能折上折,不影响此优惠码的折扣力度! Todesk作为国内优良的远程控制…

Centos系列:Centos7下的DNS服务器部署(每一步图文结合超详细,适用于初学者)

Centos7下的DNS服务器部署(每一步图文结合超详细,适用于初学者) Centos7下的DNS服务器部署引言部署步骤实验环境DNS服务端:DNS客户端: 正向解析安装DNS(DNS服务端,客户端都要操作)修…

node.js学习笔记——内部模块、自定义模块的导入和使用方式

文章目录 前文提要内部模块fs模块导入方式fs.readFilefs.writeFile path模块导入方式__dirnamepath.join http模块导入方式创建服务器实例绑定request事件启动服务器 自定义模块和第三方模块导入方式模块作用域 共享方式 前文提要 本人仅做个人学习记录,如有错误&a…

gitlab-ci.yml 同步https 仓库地址

1. 先在要部署的机器上,执行如下命令, 输入一次密码后,保存该密码git config --global credential.helper store2. 然后执行 git pull 命令, 然后会提示输入密码, 输入密码即可.3. 编写 gitlab-ci.yml 文件stages:- deploy# 部署master服务 deployMaster…

ubuntu 创建conda 环境失败 HTTP 000 CONNECTION FAILED

如有帮助点赞收藏关注! 如需转载,请注明出处! 现在内存分配好了,创建一个专门的conda环境处理文件,报错了,创建不成功! 什么情况,之前明明可以的。 百度吧。 参照一些博客修改了文档…

Linux进程切换

引入 Question&#xff1a; 为什么函数的返回值能在函数的外部被拿到呢&#xff1f;局部变量不是出了作用域就要被销毁嘛&#xff1f; #include<stdio.h>int Add(int a, int b) {int ret a b;return ret; } int main() {int a 10, b 20;int ret Add(a, b);return …