mysql的left join_mysql中的left join、right join、join

2023-05-16

sql准备

INSERT INTO name(name, age, grade) VALUES ('小白', 20, 1), ('小黑', 21, 2), ('小红', 22, 3), ('小花', 23, 4), ('小绿', 24, 5) ;

INSERT INTO classes (cname) VALUES ('欧阳锋'), ('杨过'), ('乔峰');

INSERT INTO classes (id,cname) VALUES (7, '溜哒');

62feca2f95a3d3d798a22bac67fa193c.png

6067836d973f5648134dc0f307d9b47f.png

各种join的使用

left join 即为以sql语句中的左边的表为主要表关联右边的表,其中使用on作为条件筛选,where为过滤条件

以name为主表,classes为关联表

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id;

2bffbefd7921c5e4689cbf3fd2c3d3d2.png

b4631fdc52a95d3c76e1dae3af58d139.png

可以看到小花和小绿并没有关联到classes中的任何数据,我们以name为左表,然后以classes为右表然后进行关联,展示5行数据,条件不符合的小花和小绿(没有想对应的班级、师傅领养),即为野生,需要使用null补全,而溜哒同学干脆直接无视。

以classes为主表以name为关联表

SELECT *

FROM name t1 RIGHT JOIN classes t2 ON t1.grade = t2.id;

3560c66222d3dc58d54b1562d23cd81f.png

ddeb52dae3d9fbb84a7317c75a9831df.png

可以看到以classes为主表,以name为关联表结果为4条,虽然溜哒同学什么也不会,但是还是可以下班之后溜哒溜哒溜溜狗的嘛(单身狗也是狗)!!

无主次关联join(inner join)

SELECT *

FROM name t1 JOIN classes t2 ON t1.grade = t2.id;

b3b6ae5eb90ff05ef2ccfc41f5d75f36.png

a9752372ec075c2f555266d162094511.png

而join可以看到只有两个表完全的交集才能被显示出来,这里显示3条。果然,最后登上光明顶的还是名师下边的高徒。我等可以继续溜哒溜哒。

传说中的full join(mysql不支持,使用union来进行模拟)

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id

UNION

SELECT *

FROM name t1 RIGHT JOIN classes t2 ON t1.grade = t2.id;

6fa26478758de689a025870f89dd9d62.png

d5ce23cc31efcc88729987cc7edeb3ca.png

可以看到,full join表示全并集,即6条数据。论起溜哒溜哒溜溜单身汪,溜哒同学还是可以的。

综上所述,可以整理得到:以哪个表为主表则检索出哪个表的全部内容,关联表中符合on关联要求的可以进行数据关联,如果不符合要求,那么需要以null行展示;如果使用join进行关联那么无主次关联,只显示符合要求的数据。

on、where的使用

on:两个表关联的时候使用,决定被关联的表的数据是否能与主表关联(name left join classes on name.grade = classes.id)主表name数据完全显示,不被关联的数据需要在grade侧以null数据补全

where:两个表关联后,再进行条件过滤

区别:on主要作用再被关联表中,where作用在关联后的左右数据上

基本作用

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id

WHERE t2.id IN (1, 3);

b27f6eae6748fe1635660d64673b6358.png

然后,把where中的条件拿到on中

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id AND t2.id IN(1,3);

26df5b5091c8765cc9a37525376f36b1.png

可以看到,加上where条件后作用再left join on关联后的数据,将不符合where条件的全部去掉,只使用on,和我们先前得到的结论一致,不符合关联条件的需要null行补充。

on where 约束力相同的时候

先回顾一下join(inner join)。

SELECT *

FROM name t1 JOIN classes t2 ON t1.grade = t2.id AND t2.id IN(1,3);

91628043469e79b30186b614d49228ae.png

得到join条件的两条数据。如果我们把追加的t2.id in(1,3)拿到where中是什么情况呢?

SELECT *

FROM name t1 JOIN classes t2 ON t1.grade = t2.id

WHERE t2.id IN(1,3);

91628043469e79b30186b614d49228ae.png

可以看到,此处的t2.id IN(1,3)在on和在where中效果一样。溜哒同学表示可以理解为是join关键词造成的,应为join表示完全符合条件的才进行关联展示,不会进行数据null行补充,而where用于过滤数据,那么也是表示符合条件的进行展示。(如果问我为啥不把 t1.grade = t2.id也拿到where中去,那么同学可以自己动手试试嘛!)

各种join、on、where该怎么联合使用

首先拿出最开始的例子,普通left join和on使用,展示5条数据。

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id

b57cccc26f8f4e0c20d0f389564e3ef9.png

然后我们进行数据统计,使用count()来进行查看数据条数。

SELECT count(t1.id)

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id;```

![count(name.id).png](http://upload-images.jianshu.io/upload_images/3935727-d3d73cdfd053008b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

SELECT count(t2.id)

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id;

![count(classes.id).png](http://upload-images.jianshu.io/upload_images/3935727-9ffa8ca198c539a8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

这里可以看到count(null)是不计入数据统计的(不要问为什么),那么可以看出,关联后的统计在各自部分统计是没有什么问题的,name表侧是5条,而符合on条件的classes侧是3条。由此,可以引申出另一个容易出错的地方:在on中如果有多个条件进行关联限制,此时如果这些条件中有想进行过滤的那么需要拿到where中去,才会进行正确数据筛选。

####多on条件搭配where使用(不要用错)

SELECT *

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id AND t2.id IN(1, 3);`

26df5b5091c8765cc9a37525376f36b1.png

count(t1.id) = 5

count(t2.id) = 2

这里如果想要统计符合classes.id in(1,3)的数据的时候,一定要把t2.id in(1,3)拿到where中去。比如,希望统计西毒、乔峰这两个前辈的高徒的年龄和需要将t2.id in(1,3)放到where中去。

SELECT sum(t1.age)

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id AND t2.id IN(1, 3);

214504f08e840f0e5ebf6f96e8a0420e.png

SELECT sum(t1.age)

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id

WHERE t2.id IN(1, 3);

48e0ed92d83a365e8b3ea962fda997c3.png

那么有没有可能不用where数据也能统计对的情况呢?

必然有(就好像数学老师说,这道题选A对不对啊??大多数情况下不对。。。),两个表进行关联,不使用where,但是当两部分有计算操作的时候,效果是理想的。

我们操作name中的age去加上classes中的id,(就当做师傅给徒弟传各自id数值的年限的内力)

SELECT t1.age+t2.id

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id AND t2.id IN(1, 3);

9495aa3469b895d719e26188c4d2a860.png

SELECT t1.age+t2.id

FROM name t1 LEFT JOIN classes t2 ON t1.grade = t2.id

WHERE t2.id IN(1, 3);

fff9a2357eab204a293238c2a6f9c0be.png

如上,两部分进行了加和计算操作,这时候如果再进行sum()等统计操作,其实出来的数据是一样的。使用规范,看你所在团队更倾向于哪一种。当然,如果这里使用join 内连接,那么就没有这么多不同了。

关于性能

首先必须明确的事情就是:

使用关联肯定是要从关联表中拿数据进行展示。

数据库输出的数据越多,性能越低。

数据库有自己的优化引擎,可能会将你的sql语句进行自我优化。

溜哒同学本身技术不好,这次不进行性能讨论,从输出上来看join性能要好一些,但是在工作中会存在明显的left join比join快的情况,网上都是说select中的统计并没有用到关联表的数据,所以存在数据库优化将关联表不进行关联,然后直接进行统计的情况,此时,join还是需要进行关联(双向的), 所以会出现left join 比join快的情况。同时也会出现索引使用的问题。

当然这只是网上的文章,不是自己操作的没有办法说服自己,还是多看看书,做点小实验明确一下。(会有人看么?衰.jpg)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql的left join_mysql中的left join、right join、join 的相关文章

  • 发送 QUERY 数据包时出错。 PID=9565

    我有两个不同的环境开发和生活几乎都是相同的 但上述 标题中 警告仅在开发模式下发生 在此警告之前 我还收到错误消息 允许的内存大小 268435456 字节已耗尽 这仅发生在开发模式下 使用 PHP 版本 5 6 和 mysql 不是 my
  • PHP 与 MySQL 中的资源 id #6 错误

    我这是为了我正在制作的投票系统 此代码向用户显示了他们可以从中选择的问题列表 div class main questions p class style1 style2 strong Select Your Question strong
  • .NET、C#、LINQ、SQL 和 OR 映射 - 我只是不明白:(

    我只是不明白 我什至不确定我是否在寻找正确的方向 问题 这就是我的 C 应用程序 我通过 SSH 连接到在线 MySQL 数据库 现在我可以使用 MySQL Connector Net 驱动程序 http dev mysql com dow
  • 在“读取初始通信数据包”时失去与 MySQL 服务器的连接,系统错误:61

    3天了 已经碰壁了 我正在运行 mac os x 我已经安装了mysql 5 5 14 osx10 6 x86 64 dmg 就上下文而言 我需要安装 mysql gem 以便与 ruby on Rails 一起使用 除非有一个有效的 my
  • 如果 HBase 不是运行在分布式环境中,它还有意义吗?

    我正在构建数据索引 这将需要以形式存储大量三元组 document term weight 我将存储多达几百万个这样的行 目前我正在 MySQL 中将其作为一个简单的表来执行 我将文档和术语标识符存储为字符串值 而不是其他表的外键 我正在重
  • 如何在MySQL中使用数字字符串的比较运算符?

    我有一个员工表 有类似领域的经验VARCHAR类型 此字段结合了用短划线 分隔的总年份和总月份 因此我必须按年份过滤具有 3 年以上经验的经验 我的表结构 所以现在我必须获得3年以上经验的id 我尝试如下 SELECT FROM emplo
  • AWS EMR PySpark 连接到 mysql

    我正在尝试使用 jdbc 通过 pyspark 连接到 mysql 我可以在 EMR 之外完成此操作 但是当我尝试使用 EMR 时 pyspark 无法正确启动 我在我的机器上使用的命令 pyspark conf spark executo
  • 如何使用 zend paginate 而不加载数据库的所有结果

    所以我认为 zend paginate 工作的方式是 paginator Zend Paginator factory results paginator gt setItemCountPerPage itemCount paginator
  • 如何保证auto_increment数字没有间隙?

    我有一个关于自动递增的问题 这是我的表 我首先拥有它 它可以顺利地递增 id id name 1 name1 2 name2 3 name3 4 name4 5 name5 6 name6 但是当我删除一条记录并插入一条新记录时 id从7开
  • 如何设置 MySQL Workbench 自动断开与服务器的连接?

    有没有办法设置Workbench在空闲时自动与服务器断开连接 命令行 mysql 客户端在空闲时断开连接 然后在运行查询时重新连接 我也希望 Workbench 自动断开连接 我无法修改服务器的超时设置 但命令行客户端可以按照当前服务器设置
  • 在 R 中连接/匹配数据帧

    我有两个数据框 第一列有两列 x是水深 y是每个深度的温度 第二个也有两列 x也是水深 但与第一个表中的深度不同 第二栏z是盐度 我想通过以下方式连接两个表x 通过增加z到第一张桌子 我已经学会了如何使用 key 来连接表tidyr 但只有
  • 错误:mysqladmin:刷新失败;错误:“未知错误”

    当我厌倦了每天从 Cron Daemon 收到电子邮件时 我的问题就开始了 电子邮件如下所示 From Cron Daemon lt email protected cdn cgi l email protection gt Date 20
  • 查找返回的 mysql 结果中的行数(nodejs)

    当使用 felixge 的 mysql for node js 时 如何向结果对象询问返回的行数 我有一个相当昂贵的查询 所以我不想运行COUNT 首先 只是为了第二次运行查询 如果是选择查询 则只需获取返回数组的长度即可 connecti
  • 在重复键上仅更新 Null 或空值

    我有一个 mysql 查询来合并主键 IMO 上的两个表 查询工作正常 但我遇到的问题是在重复键更新时 我只想更新 wp second 表的那些没有值的字段 简而言之 在重复键上 wp second 值仅应在 null 或空时更新 这是我到
  • Python Pandas to_sql,如何创建带有主键的表?

    我想使用 Pandas 的 to sql 函数创建一个 MySQL 表 该函数有一个主键 在 mysql 表中拥有主键通常是件好事 如下所示 group export to sql con db name config table grou
  • 选择特定值之后的项目

    说这是我的sql SELECT title author ISBN FROM bs books ORDER BY ISBN LIMIT 3 它只是从某个表中选择所有内容 标题 作者等 假设我想选择某个标题后面的所有项目 而不是按字母顺序或其
  • Sequel Pro / MAMP 在哪里存储本地数据库?

    我通过 Sequel Pro 和 MAMP 在我的计算机上创建了一些数据库 并运行 localhost 来查看它们 但是 我全新安装了 Mac OS Lion 但忘记将数据库备份到 sql 文件 我会定期备份文件 并预装计算机的副本 有谁知
  • 为什么多表连接会产生重复行?

    假设我有三个表 A B 和 C 每个表都有两列 一个主键和一些其他数据 它们每个都有相同的行数 如果我JOIN主键上的 A 和 B 我最终应该得到与其中任何一个相同的行数 而不是 A rows B rows 现在 如果我JOIN A JOI
  • 如何在node-mysql查询后获取警告

    如何获取查询执行后识别的相应警告 如下所示 connection query squery function err rows search for OkPacket in 2 dimension array var warningCoun
  • 在mysql查询中对多个日期范围求和

    我有一个 MySql 表 产品 包含三列 Date Product Qty 我的目标是每周对每种产品的数量进行求和 获取两个给定日期之间的 SUM 很容易 SELECT SUM qty FROM products WHERE date gt

随机推荐