MSQL系列(十四) Mysql实战-SQL语句 left join inner join On和Where语句的区别

Mysql实战-SQL语句On和Where语句的区别

前面我们讲解了Join的底层驱动表 选择原理,也知道了基本的内连接外连接两种SQL查询表连接方式
但是我们再查询多表的时候on和where语句到底有什么区别?

  • where是过滤条件 ,不满足where的一定不会出现在结果中
  • on是连接条件, 对于内连接来说 on和where效果一致
  • 对于外连接来说, 如果在被驱动表中无法匹配on的过滤条件,该记录是要加入到结果集中
  • 不符合匹配条件的被驱动表的数据,全部用NULL值填充
  • 先 on 再left join 再where
  • 使用on关键字时,会先根据on后面的条件进行筛选,条件为真时返回该行
  • on的优先级高于left join,所以left join关键字会把左表中没有匹配的所有行也都返回,然后生成临时表返回
  • where对与行的筛选是在left join之后的,也就是生成临时表之后对临时表进行筛选

下面我们来实战SQL演练一下

文章目录

      • Mysql实战-SQL语句On和Where语句的区别
        • 1.建表及测试数据
        • 2. 内连接的on连接过滤条件等同于where过滤条件
        • 3.left join 外连接 on 连接条件
        • 4.left join where 过滤条件
        • 5.更复杂的 on 和 where的对比

1.建表及测试数据

我们先创建两个表 test_user 和 test_order 这两个表作为我们的测试表及测试数据

  • test_user 5条数据, 索引只有主键id
  • test_order 3条数据,索引同样也只有主键id
#创建test_user
CREATE TABLE `test_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名字',
  `age` int DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (`id`),
  KEY `idx_age` (`age`),
  KEY `idx_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

#创建表 test_order
CREATE TABLE `test_order` (
  `id` int NOT NULL AUTO_INCREMENT,
	`user_id` int NOT NULL COMMENT '用户id,就是test_user的唯一主键id',
  `order_name` varchar(32) NOT NULL DEFAULT '订单信息',
  `pay` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';

插入数据

#插入 user 用户数据
INSERT INTO `prepare`.`test_user` (`id`, `user_name`, `age`) VALUES (1, 'aa', 10);
INSERT INTO `prepare`.`test_user` (`id`,  `user_name`, `age`) VALUES (2, 'bb', 20);
INSERT INTO `prepare`.`test_user` (`id`,  `user_name`, `age`) VALUES (3, 'cc', 30);
INSERT INTO `prepare`.`test_user` (`id`, `user_name`, `age`) VALUES (4, 'dd', 40);

#插入 order 订单数据
INSERT INTO `prepare`.`test_order` (`id`, `user_id`, `order_name`, `pay`) VALUES (1, 1,'衣服', 100);
INSERT INTO `prepare`.`test_order` (`id`, `user_id`, `order_name`, `pay`) VALUES (2, 2,'鞋子',  200);
INSERT INTO `prepare`.`test_order` (`id`, `user_id`, `order_name`, `pay`) VALUES (3, 2,'电视',  300);

根据表记录 可以知道

  • user用户表有4个用户, aa,bb,cc,dd
  • order订单表有 1,2,3 个订单, aa一条衣服, bb用户一个鞋子,一个电视

在这里插入图片描述

2. 内连接的on连接过滤条件等同于where过滤条件

当连接条件是 inner join内连接时, on连接的过滤条件 等同于 where 过滤条件

也就是说 你把过滤条件 放到 on 语句后面 或者放到 where 语句后面,效果是一致的

#on语句过滤条件
select * from test_user inner join test_order on test_user.id = test_order.user_id;
#where语句作为过滤条件
select * from test_user inner join test_order where test_user.id = test_order.user_id;

在这里插入图片描述

3.left join 外连接 on 连接条件

left join外连接的时候, on 连接条件过滤 和 where 条件过滤 区别就很大了, on 条件是 被驱动表 不匹配的也要展示, 用NULL来填充

但是 where语句就是 不满足的全部都过滤掉, 下面我们来实际看下效果

  • on语句 的过滤条件, 不符合的展示出来,用NULL填充
#找出驱动表
explain select * from test_user left join test_order on ( test_user.id = test_order.user_id)  and test_order.user_id = 2;
#查询结果
select * from test_user left join test_order on ( test_user.id = test_order.user_id)  and test_order.user_id = 2;

查看结果

  • test_user是驱动表, 那么test_order就是被驱动表
  • on 条件是 ( test_user.id = test_order.user_id) and test_order.user_id = 2
  • 是否只返回了 test_order.user_id = 2 的数据 ? 并不是, user_id 不等于2的也都返回了
  • 只不过 她们的被驱动表数据 order 的数据 全都是 NULL填充的
  • 所以 on 后面的过滤条件, 不是做过滤的,而是做匹配的, 不匹配的用NULL填充
    在这里插入图片描述在这里插入图片描述
4.left join where 过滤条件

前面我们看到了 用 on 去 连接两个表, 并且设置了 test_order.user_id = 2
但是返回结果 并不是 user_id = 2的数据, 而是 不匹配的数据用NULL来代替了

如果是 where 语句呢?
如果说 test_order.user_id = 2 挂在where语句后面 效果是什么样子呢?

#查看驱动表
explain
select * from test_user left join test_order on ( test_user.id = test_order.user_id)  where test_order.user_id = 2;

#执行查询语句
select * from test_user left join test_order on ( test_user.id = test_order.user_id)  where test_order.user_id = 2;

查看执行结果

  • test_user是驱动表, 那么test_order就是被驱动表
  • on 条件是 ( test_user.id = test_order.user_id)
  • where 条件是 where test_order.user_id = 2
  • 数据结果只有 test_order.user_id = 2 的数据 才返回, 别的 都不返回
  • 所以 where 后面的过滤条件, 就是做过滤的, 只要where不满足, 结果就不会满足
    在这里插入图片描述
    在这里插入图片描述
5.更复杂的 on 和 where的对比

如果 上面的例子 你还是没区分出来 on 和 where的 区别, 我们再来一个更加直观的, 一眼就看出来区别

#on 条件
select * from test_user left join test_order on  test_user.id = test_order.user_id  and test_order.pay > 100;
#where 条件
select * from test_user left join test_order on  test_user.id = test_order.user_id  where test_order.pay > 100;

我们看下执行结果

  • on条件查询
    • pay > 100 的 数据返回
    • pay <= 100的也有一条, 但是都用NULL填充了
    • 返回了 驱动表 test_user 连接 被驱动表 test_order 的符合数据的所有数据 5条数据 且 >100 的 2条 正常展示
    • pay <= 100的数据 用NULL填充
    • on先执行 , 连接条件生成临时表, 所以数据就在那里了, 5条数据
    • 然后 匹配 pay >100 的2条, 匹配展示, 其余的 全都 NULL填充
  • where 条件查询
    • 结果 只有2条数据 pay>100 的就2条数据
    • where是基于临时表去过滤的
    • 不满足的不会呈现到返回结果

在这里插入图片描述


至此,我们已经彻底分清楚了 on语句和where语句的区别, 这对于我们能够正确的处理业务,十分重要

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SPASS-描述性分析

将身高移入变量 结果展示&#xff1a; 表中分析变量“身高”的个案数、所有个案中的极大值、极小值、均值、标准差及偏度和峰度

【React】04.MVC模式和MVVM模式

React是Web前端框架 1、目前市面上比较主流的前端框架 ReactAngular&#xff08;NG框架&#xff09;Vue 主流的思想&#xff1a; 不在直接去操作DOM&#xff0c;而是改为“数据驱动思想” 操作DOM思想&#xff1a; 操作DOM比较消耗性能[主要原因就是&#xff0c;可能会导…

【C/PTA——7.数组1】

C/PTA——7.数组1 7-1 计算最大值出现的次数1.题目要求2.代码实现 7-2 求一批整数中出现最多的个位数字1.题目要求2.代码实现 7-3 装箱问题1.题目要求2.代码实现 7-4 数组-值钱的微信号1.题目要求2.代码实现 7-5 数组-吹泡泡1.题目要求2.代码实现 7-6 数组-数学鬼才1.题目要求2…

JavaWeb Day05 前后端请求响应与分层解耦

目录 一、请求与响应 &#xff08;一&#xff09;请求的参数接收 ①数组参数 ②集合参数 ③日期参数 ④json参数 ⑤路径参数 总结 &#xff08;二&#xff09;响应 ①简单文本text ②数组 ③列表 ④同一响应数据格式 ⑤总结 二、三层架构与分层解耦 &#xff0…

前端特殊字符转码

前端特殊字符转码 建议 最好不要传名称&#xff0c;传ID 是在不行就用这个方法 name encodeURIComponent(name),

医院检验信息管理系统源码 医院LIS系统源码 云LIS源码 区域LIS源码

医院检验信息管理系统源码 医院LIS系统源码 云LIS源码 区域LIS源码 医院检验信息管理系统&#xff0c;利用计算机网络技术、数据存储技术、快速处理技术&#xff0c;对检验科进行全方位信息化管理&#xff0c;使检验科达到自动化运行&#xff0c;信息化管理和无纸化办公的目的…

【C++】万字详解IO流(输入输出流+文件流+字符串流)

文章目录 一、标准输入输出流1.1提取符>>&#xff08;赋值给&#xff09;与插入符<<&#xff08;输出到&#xff09;理解cin >> a理解ifstream&#xff08;读&#xff09; >> a例子 1.2get系列函数get与getline函数细小但又重要的区别 1.3获取状态信息…

矩阵键盘独立接口设计(Keil+Proteus)

前言 实验&#xff1a;通过4*4的矩阵键盘&#xff0c;按下某个按钮之后会在数码管上面显示对应的键号。&#xff08;0~F&#xff09; 基础操作参考这篇博客&#xff1a; LED数码管的静态显示与动态显示&#xff08;KeilProteus&#xff09;-CSDN博客https://blog.csdn.net/w…

13 # 手写 concat 方法

concat 的使用 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组&#xff0c;而是返回一个新数组。如果省略了所有参数&#xff0c;则 concat 会返回调用此方法的现存数组的一个浅拷贝。 <script>var arr1 ["k", "a", "i"…

Python tkinter库的Menu组件实现菜单栏、一级菜单、二级菜、三级菜单

在Python的Tkinter中&#xff0c;要显示菜单栏、一级菜单、二级菜、三级菜单&#xff0c;可以使用add_cascade方法将下一级菜单添加到上一级菜单中。 运行结果 下面是一个简单的示例&#xff1a; import tkinter as tkroot tk.Tk()# 创建菜单栏 menubar tk.Menu(root) root…

官方Redis视图化工具Redisinsight

一、下载最新版本的 docker pull redislabs/redisinsight mkdir /data/redisinsight docker run -d -u root -p 8001:8001 -v /etc/localtime:/etc/localtime -v /data/redisinsight:/db --restartunless-stopped redislabs/redisinsight:latest 二、浏览器打开 http://192…

C#解析XML并反序列化为Model的方法

虽然现在json大行其道&#xff0c;但是xml格式依旧占据着广阔的编程世界&#xff0c;不管光伏锂电激光卫星汽车等等工业领域&#xff0c;基本上都是以xml为主&#xff0c;广大的.NET开发人员有很多被xml折磨的都要转java了&#xff0c;这篇小作文就来玩一种迅速完成xml到model的…

DuiLib中常用各种RGB颜色对照表

【常识】常用RGB颜色对照表] 颜色样式***RGB*数值颜色代码颜色样式***RGB*数值颜色代码黑色0,0,0#000000白色255,255,255#FFFFFF象牙黑88,87,86#666666天蓝灰202,235,216#F0FFFF冷灰128,138,135#808A87灰色192,192,192#CCCCCC暖灰128,118,105#808069象牙灰251,255,242#FAFFF0石…

Vue 入门案例剖析

vscode 启用open with live server功能&#xff0c;配置谷歌浏览器chrome_小头猿的博客-CSDN博客 之所以使用vue就是想让其帮我们构建页面&#xff0c;构建出来了页面但是摆在那个位置呢&#xff1f;所以得准备好一个容器&#xff0c;最起码得有东西去承接这个界面。 控制台这…

红海云签约和兆服饰,科技引领服饰行业人力资源数字化转型

和兆服饰从事多品牌多品类经营管理&#xff0c;旗下拥有POLOSPORT、POLOKIDS、CARTELO等国际品牌。作为一个主打POLO文化的服饰品牌&#xff0c;诞生于美国的POLOSPORT拥有现代感的产品设计、系列化的产品搭配、全方位的服务&#xff0c;是最具美国马球精神的休闲时尚服饰品牌之…

暖通空调系统使用Modbus转Profinet网关应用配置案例

PLC通过兴达易控Modbus转Profinet网关&#xff08;XD-MDPN100)控制暖通空调的温度、湿度。作为控PLC可以通过Modbus传输到Profinet网关&#xff0c;与空调系统的压缩机进行通信&#xff0c;从而准确控制单元的加热、加湿、冷却和减湿。PLC可以实时监控和调整空调系统的运行状态…

给VSCode插上一双AI的翅膀

#AI编程助手哪家好&#xff1f;DevChat“真”好用# 文章目录 前言一、安装DevChat1.1、访问地址1.2、注册1.3、在VSCode里安装DevChat插件1.3.1、未安装状态1.3.2、已安装状态 二、设置Access Key2.1. 点击左下角管理&#xff08;“齿轮”图标&#xff09;—命令面板&#xff…

mac 卸载第三方输入法

输入法设置里的移除&#xff0c;并不是真的卸载&#xff0c;点击还是能添加回来 在活动监视器里强制退出此输入法在访达界面使用快捷键 ShiftcommandG在弹出的对话框内输入以下路径&#xff08;/资源库/Input Methods&#xff09;&#xff0c;再点击下面的前往找到你要卸载的输…

【深度神经网络(DNN)】实现车牌识别

文章目录 前言一、数据集介绍二、步骤1.导包2.参数配置3.数据处理4.模型定义5.模型训练6.模型预测 总结 前言 课内实践作业 车牌识别 一、数据集介绍 1.车牌识别数据集&#xff1a;VehicleLicense车牌识别数据集包含16151张单字符数据&#xff0c;所有的单字符均为严格切割且…