当前位置: 首页 > news >正文

MySql 别犯糊涂了! LEFT JOIN 的 ON 后接上筛选条件,多个条件会出事!

很多时候我们在使用  LEFT JOIN   ...... ON .... 时, 除了连接两个表的字段条件外,我们往往还需要一些等值或者范围 等等类似的数据筛选条件。

那么对于初学者,往往会犯一个错误,就是 想当然 地 认为, ON 后面的条件是逐一执行的,因为没有了解清楚 ON 后面接条件的规则。

是个什么样的场景? 

看实例讲解:

userinfo 表 :

(找兼职的人员名单信息表)

jobinfo表 :

(兼职工作信息及职业要求表)

业务需求:

根据职业要求 给 找兼职的人员 匹配上 目前 可以做的兼职,输出数据条。 

例如,李三是一个程序员,他迫于经济压力,不得不向社会低头,想找一些自己能做的兼职。

使用 WHERE

如果我们不用  left join ...... on ... , 仅仅使用 where,那么简单写下sql是:

SELECT * 
FROM userinfo AS u ,jobinfo AS j 
WHERE u.userProfession=j.professionRequire
AND j.professionRequire='程序员'

查询出来的结果如下:

是我们需要的结果,可以看的,程序员李三能做的兼职有,送外卖或者当保安。 

使用 LEFT JOIN ...... ON  ......

初学者(罪过)写的SQL :

想当然地把筛选条件 职业要求为 ‘ 程序员’  直接 拼接在 ON 后面

SELECT * 
FROM userinfo AS u 
LEFT JOIN   
jobinfo AS j 
ON u.userProfession=j.professionRequire
AND j.professionRequire='程序员'

这样地拼接筛选条件其实是达不到所想要的效果的,先来看看这样的执行结果:

可以看到查询出来很多我们不想要的数据,为什么会这样?

原因:

因为如果直接把关联表的筛选条件拼接在 ON 后, 执行的顺序其实是:

先将 jobinfo 表 按照筛选条件  professionRequire='程序员'  执行后作为子查询,再执行 LEFT JOIN ...... ON 。

也就是第一步变成了执行  SELECT *  FROM jobinfo AS j  WHERE  j.professionRequire='程序员'  

然后再进行连接查询,也就是 

整个sql语句其实变成了:

SELECT * 
FROM userinfo AS u 
LEFT JOIN   
(SELECT *  FROM jobinfo  WHERE jobinfo.professionRequire='程序员') AS j 
ON 
u.userProfession=j.professionRequire

 这样查询出来,显然不是我们想要的结果。

那么我们在使用 LEFT JOIN ...... ON  ...... 拼接筛选条件时,我们应该怎么做?

配合 WHERE 使用:

SELECT * 
FROM userinfo AS u 
LEFT JOIN   jobinfo AS j 
ON u.userProfession=j.professionRequire
WHERE j.professionRequire='程序员'

结果:

我们把筛选条件配合where去使用, 执行的逻辑就是:

先执行LEFT JOIN ...... ON  ......  先将关联两个表之后的数据查询出来;

再按照 professionRequire='程序员'   条件,进行数据筛选。

所以这是我们想要得到的结果。

这是一个使用 LEFT JOIN 的 ON  初学者很容易犯的错误,大家稍微注意点。

相关文章:

  • 微服务 分布式事务解决方案
  • MySql 索引失效、回表解析
  • Springboot 超简单实现在线预览,Word文档 doc、xlsx、pdf、txt等
  • Java 结合实例学会使用 静态代理、JDK动态代理、CGLIB动态代理
  • Springboot 实现 上传、下载 以及解决必须项目重启才能访问资源的问题
  • JAVA 获取微信用户信息,看完这篇你必须得学会
  • Java 求助! 为什么我拿不到错误信息,e.getMessage()
  • Java 获取范围内的随机整数
  • Xshell6 提示更新,使用不了! 解决方案
  • Springboot 前端请求的每次sessionid 都不同
  • Springboot mavne项目多模块打包,报错 找不到 base包,找不到common类等等
  • 浅谈乐观锁的设计
  • Mysql 唯一索引的字段值 允许多个NULL值存在吗
  • Springboot @Autowired 和 @Resource 我的剖析,你看完就不会忘
  • Springboot 调用mysql的.sql文件,执行mysql语句
  • php的引用
  • Android 架构优化~MVP 架构改造
  • Android 控件背景颜色处理
  • conda常用的命令
  • Linux后台研发超实用命令总结
  • overflow: hidden IE7无效
  • socket.io+express实现聊天室的思考(三)
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 搞机器学习要哪些技能
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 如何学习JavaEE,项目又该如何做?
  • 三分钟教你同步 Visual Studio Code 设置
  • 试着探索高并发下的系统架构面貌
  • 小程序开发中的那些坑
  • PostgreSQL之连接数修改
  • scrapy中间件源码分析及常用中间件大全
  • 仓管云——企业云erp功能有哪些?
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • # centos7下FFmpeg环境部署记录
  • #define、const、typedef的差别
  • #if #elif #endif
  • #考研#计算机文化知识1(局域网及网络互联)
  • (二)linux使用docker容器运行mysql
  • (附源码)计算机毕业设计高校学生选课系统
  • (十)T检验-第一部分
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (转)创业的注意事项
  • .net CHARTING图表控件下载地址
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET 发展历程
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET大文件上传知识整理
  • .NET开发人员必知的八个网站
  • .NET中GET与SET的用法
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [16/N]论得趣
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记
  • [Android Pro] listView和GridView的item设置的高度和宽度不起作用
  • [cocos creator]EditBox,editing-return事件,清空输入框