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

news2024/10/6 20:32:24

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语句的区别, 这对于我们能够正确的处理业务,十分重要

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

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

相关文章

Leetcode—2731.移动机器人【中等】

2023每日刷题&#xff08;二十二&#xff09; Leetcode—2731.移动机器人 算法思路 参考自灵茶山艾府 实现代码 class Solution { public:const int MOD 1e9 7;int sumDistance(vector<int>& nums, string s, int d) {int n nums.size();vector<long long…

使用<a>标签进行文件下载出现文件名称乱码、文件名变下划线

在使用a标签下载文件时出现了如图所示文件名称显示错误&#xff0c;原因是因为文件中包含中文导致乱码 解决方法使用axios配合Blob&#xff0c;如果项目中没有安装或者不想安装axios使用Ajax跟fetch也是一样可以解决&#xff1a; 使用axios&#xff08;记得引入axios&#xff0…

JJJ:PCI / PCIE 的一些术语和概念

转发事务和非转发事务 在PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;总线中&#xff0c;存在两种类型的事务&#xff1a;转发事务和非转发事务。 1、转发事务&#xff08;Forwarded Transactions&#xff09;&#xff1a;转发事务是指从一个PCIe…

openvpn使用

如何使用OpenVPN搭建局域安全网_宝塔搭建vpn_幸识SQ的博客-CSDN博客 OpenVPN在CentOS7中最简单的搭建局域网_哔哩哔哩_bilibili 最终的效果是&#xff0c;如果安装好服务端后&#xff0c;会生成一个文件&#xff0c;要用到客户端。 客户端安装后&#xff0c;会多个IP 这样&…

关于unity中 编辑器相关逻辑的记录

prefab 在场景中 , 用这个方法可以获取它的磁盘路径: [MenuItem("Gq_Tools/↓获取prefab路径")] public static void SaveDecalParameters() { var objs Selection.objects; var obj objs[0] as GameObject; Object parentObject Prefab…

Amazon MSK 基于 S3 的数据导出、导入、备份、还原、迁移方案

Amazon MSK&#xff08;Amazon Managed Streaming for Apache Kafka&#xff09;是 Amazon 云平台提供的托管 Kafka 服务。在系统升级或迁移时&#xff0c;用户常常需要将一个 Amazon MSK 集群中的数据导出&#xff08;备份&#xff09;&#xff0c;然后在新集群或另一个集群中…

Linux之打印函数调用依赖关系(六十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

extractvalue报错注入理论及实战

报错注入 什么是报错注入 构造语句&#xff0c;让错误信息中夹杂可以显示数据库内容的查询语句&#xff0c;返回报错提示中包括数据库中的内容 如上图所示&#xff0c;通过group by的报错&#xff0c;我们可以知道列数是多少 输入正确的查询数据库的SQL语句&#xff0c;虽然可…

理解交叉熵(Cross Entropy)

交叉熵&#xff08;Cross-Entropy&#xff09;是一种用于衡量两个概率分布之间的距离或相似性的度量方法。在机器学习中&#xff0c;交叉熵通常用于损失函数&#xff0c;用于评估模型的预测结果与实际标签之间的差异。 在分类问题中&#xff0c;交叉熵损失函数通常用于多分类问…

如何在公文套红过程中设置页码

zOffice的套红功能&#xff0c;是把源文件套入到公文模版的书签中去&#xff0c;将两个文件合成一个&#xff0c;那么源文件的一些设置可能会保留也可能会被重置&#xff0c;那么如何在公文套红中保留页码设置呢&#xff1f;当然是通过zOffice丰富的SDK接口来实现控制了&#x…

WebGL软件项目类型

WebGL&#xff08;Web Graphics Library&#xff09;是一种用于在Web浏览器中渲染3D和2D图形的JavaScript API。它提供了强大的能力&#xff0c;可以用于开发各种类型的项目&#xff0c;包括但不限于以下几种&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xf…

Vue 3 中,watch 和 watchEffect 的区别

结论先行&#xff1a; watch 和 watchEffect 都是监听器&#xff0c;都是用来监听响应式数据的变化并执行相应操作。区别是&#xff1a; watch&#xff1a;需要指明要监听的数据&#xff0c;而且在回调函数中可以获取到属性变化的前后值&#xff1b; 适用于需要精确控制监视…

学习在echarts中优化数据视图dataView样式带表格样式,支持复制功能

学习在echarts中优化数据视图dataView样式 带表格样式 toolbox里有个dataView视图模式&#xff0c;里面的数据没有对整&#xff0c;影响展示效果&#xff0c;情形如下&#xff1a; 像这种标题跟数据没有整齐对应上&#xff0c;看起来乱 改问题解决方案为&#xff0c;option 》…

IO多路复用 Linux C Server-Client 多用户聊天系统

目录 Server-Client mutiplexingServer mutiplexingClient mutiplexing Server-Client 在Linux系统中&#xff0c;IO多路复用是一种机制&#xff0c;它允许一个进程能够监视多个文件描述符&#xff08;sockets、pipes等&#xff09;的可读、可写和异常等事件。这样&#xf…

6-会话、过滤器、监听器

6-会话、过滤器、监听器 文章目录 6-会话、过滤器、监听器会话会话概述为什么需要会话管理会话管理实现的手段 Cookie概述使用时效设置路径设置&#xff1a;特定请求才携带cookie SessionHttpSession的概述HttpSession的使用HttpSession的使用-getSession()方法原理HttpSession…

Django快速指南

开始构建 Web 应用程序不仅需要对编码和设计原则有深入的了解&#xff0c;还需要对安全性和性能坚定不移的承诺。在数字化存在至关重要的时代&#xff0c;构建强大而高效的在线平台的能力是一项具有不可估量价值的技能。本教程专门面向网络工匠&#xff0c;即那些希望将技术线索…

提高 bbr 的灵敏性

bbr draft 给出了 MaxBwFilterLen 的定义&#xff1a; MaxBwFilterLen: The filter window length for BBR.MaxBwFilter 2 (representing up to 2 ProbeBW cycles, the current cycle and the previous full cycle). 从 v1 到 v3 版本&#xff0c;该值均只跟状态机而不跟实际&…

#龙迅视频转换IC LT7911D是一款高性能Type-C/DP/EDP 转MIPI®DSI/CSI/LVDS 芯片,适用于VR/显示应用。

1.说明 应用功能&#xff1a;LT7911D适用于DP1.2转MIPIDSI/MIPICSI/LVDS&#xff0c;EDP转MIPIDSI/MIPICSI/LVDS&#xff0c;TYPE-C转MIPIDSI/MIPICSI/LVDS应用方案 分辨率&#xff1a;单PORT高达4K30HZ&#xff0c;双PORT高达4K 60HZ 工作温度范围&#xff1a;−40C to 85C 产…

Discourse 如何在 header 上添加 HTML

虽然现在大部分网站都开始支持使用 CDN 的网站校验了。 但还有些网站在你需要他们提供服务的时候要求使用 header 的 meta 数据校验。 Discourse 是可以轻松的实现上面的功能的。 添加方法 选择你的 Discourse 网站下的自定义。 然后在左侧选择你需要添加的主题。 为了方便…

【EI会议征稿】第三届电气、电力与电网系统国际会议(ICEPGS 2024)

第三届电气、电力与电网系统国际会议&#xff08;ICEPGS 2024&#xff09; 2024 3rd International Conference on Electrical, Power and Grid Systems 第三届电气、电力与电网系统国际会议&#xff08;ICEPGS 2024&#xff09;将于2024年1月26-28日在马来西亚吉隆坡隆重举行…