Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级
一、Mysql中Left/Right join on后面and和where条件查询的差异
1、建两张测试表,一张商户定义表、一张商户操作状态明细表
1)商户定义表
CREATE TABLE hope.merchant (
MERCHANT_id varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2)商户操作明细表
CREATE TABLE trade_info (
MERCHANT_NO varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
TRADE_STATUS varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
CREATE_TIME datetime DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2.测试Left/Right join on后面and和where条件查询的差异
普通left join演示
select a.MERCHANT_id,b.MERCHANT_NO,b.TRADE_STATUS from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO;
select count(1) from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO;--》82行数据
结果:可以看到,部分商户在某段时间内事没有任何操作的,所以,左表hope.merchant的商户,没有对应的操作,会用Null补足。

1)Left/Right join on后面带and
select a.MERCHANT_id,b.MERCHANT_NO,b.TRADE_STATUS,b.CREATE_TIME from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO and b.CREATE_TIME>'2018-12-19 19:00:00';
select count(1) from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO and b.CREATE_TIME>'2018-12-19 19:00:00'; ----》69行数据

2)Left/Right join on后面带where
select a.MERCHANT_id,b.MERCHANT_NO,b.TRADE_STATUS,b.CREATE_TIME from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO where b.CREATE_TIME>'2018-12-19 19:00:00';
select count(1) from hope.merchant a left join hope.trade_info b
on a.MERCHANT_id=b.MERCHANT_NO where b.CREATE_TIME>'2018-12-19 19:00:00'; --》43行数据

3)对比结果
语句一是on and ,一句是 on where,下的条件类似,但是结果却是完全不同。带where的过滤掉了左连接中左表没有任何操作记录的商户号,
但是使用and的却没有,并得到了我想要的结果。Why???
二、Mysql 运算符是有优先级
1.总结SQL优先级
where是对已经搜索出的结果的过滤条件
on是两者join形成新表时用到的匹配条件
大家可能看出一些规律,在on的情况下and(或者or)与on同时对前面的集合起作用,而存在where的时候,先对集合进行on条件的抽取,在根据where的条件进行抽取.这是个值得注意的地方.
说下原因:
(1)ON后面的筛选条件主要是针对的是关联表【而对于主表筛选条件不适用】;
(2)对于主表的筛选条件应放在where后面,不应该放在ON后面;
(3)对于关联表我们要区分对待。如果是要条件查询后才连接应该把查询件放置于ON后;如果是想再连接完毕后才筛选就应把条件放置于where后面;
(4)对于关联表我们其实可以先做子查询再做join。
2.总结sql类型,尽量不写子查询
1)对于关联表我们其实可以先做子查询再做join,此SQL运行3.5秒
select MERCHANT_ID,case when rait is null then 0 else rait end
from (
select MERCHANT_ID,
TRUNCATE(count(case when c.trade_status ='SUCCESS' then 1 else null end)*100/count(case when c.trade_status !='FAILED' then 1 else null end),2) rait
from ifpay_ccpay.merchant a left join (
select * from ifpay_ccpay.trade_info b where b.CREATE_TIME > date_add(now(), interval - 30 minute)
and b.method='H5') c on a.MERCHANT_ID=c.MERCHANT_NO group by a.MERCHANT_ID) d;

2)不做子查询运行14ms
select MERCHANT_ID,case when rait is null then 0 else rait end
from (
select MERCHANT_ID,
TRUNCATE(count(case when b.trade_status ='SUCCESS' then 1 else null end)*100/count(case when b.trade_status !='FAILED' then 1 else null end),2) rait
from ifpay_ccpay.merchant a left join ifpay_ccpay.trade_info b on a.MERCHANT_ID=b.MERCHANT_NO
and b.CREATE_TIME > date_add(now(), interval - 30 minute)
and b.method='H5' group by a.MERCHANT_ID) D;

Mysql 中Left/Right join on后面and和where条件查询的差异-Mysql SQL运算符是有优先级的更多相关文章
- MySQL中使用INNER JOIN来实现Intersect并集操作
MySQL中使用INNER JOIN来实现Intersect并集操作 一.业务背景 我们有张表设计例如以下: CREATE TABLE `user_defined_value` ( `RESOURCE ...
- 关于MySQL中的left join、on、where的一点深入
原文地址:http://www.oschina.net/question/89964_65912?sort=default&p=3#answers 即使你认为自己已对 MySQL 的 LEFT ...
- 使用Mysql中的concat函数或正则匹配来快速批量生成用于执行的sql语句
背景介绍 今天需要给一张表里面补数据,需要按照行的维度进行update,如果是个别数据那么直接写update语句就可以了,但是场景要求的是将整表的数据进行update,要实现这个需求就不能只靠蛮力了, ...
- Mysql高手系列 - 第7篇:玩转select条件查询,避免踩坑
这是Mysql系列第7篇. 环境:mysql5.7.25,cmd命令中进行演示. 电商中:我们想查看某个用户所有的订单,或者想查看某个用户在某个时间段内所有的订单,此时我们需要对订单表数据进行筛选,按 ...
- oracle 在xml中批量插入,批量修改及多组条件查询
最近公司用ibatis开发项目,本来可以用存储过程处理批量插入,批量修改及多组条件查询:但由于使用模块相对较小,暂时就在xml中配置,以前没有在xml做过类似处理,有必要记录一下:好了,代码如下: & ...
- MySQL中日期与字符串相互转换,并进行日期比较查询
技术交流群:233513714 1.日期无需转换查询(日期在数据库中的类型为字符串) select * from day where dateTime > '2016-03-15' 2.使用da ...
- 多条件查询(php+mysql) 租房子例子
<body> <?php //多条件 $tiaojian2= " 2=2 "; $attr2 = ""; //判断区域 if(!empty($ ...
- MySQL中链接查询inner join与left join使用
连接查询其实就是对两个表记录做笛卡尔乘积.如果不指定连接条件的话,则会对每行都做笛卡尔乘积,这样最后返回的结果树就会是两个表记录数的乘积:如果指定则,则仅对符合列条件的行进行笛卡尔乘积,并返回结果.在 ...
- mysql中的几种join 及 full join问题
[注意]:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+ union+右外连接实现 初始化SQL语句: /*join 建表语句*/ ...
随机推荐
- ReadResolve方法与序列化
使用枚举实现的单例模式,不但可以防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象. 对于其他方式实现的单例模式,如果既想要做到可序列化,又想要反序列化 ...
- 2016年蓝桥杯B组C/C++省赛(预选赛)题目解析
2016年蓝桥杯B组C/C++ 点击查看2016年蓝桥杯B组省赛试题(无答案版) 第一题:煤球数目 题解 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个( ...
- 网络压缩论文集(network compression)
Convolutional Neural Networks ImageNet Models Architecture Design Activation Functions Visualization ...
- Unity3D学习笔记(二十一):InputFiled、Dropdown、Scroll Rect、Mask
InputFiled组件(输入框) Text Component(显示内容):显示输入内容的Text的组件 Text(输入内容):输入的文本内容 Character Limit:字符数量限值,0是无限 ...
- echart提示框内容数据添加单位
本文为博主原创,转载须注明转载地址: 方法为: tooltip : { trigger: 'axis', formatter: '{a0}:{c0}%' }, legend: { data:['测试' ...
- c# 、 Asp.net 获取本地IP和MAC地址
using System; using System.Management; using System.Net; public class Program { static void Main(str ...
- MVC ---- EF批处理
#region 批处理 ///<summary> ///两增一删一改 ///</summary> public void Save(){ //新增参一 Parameter pa ...
- python 斐波那契查找
def fibonacci_search(lis, key): # F = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 ...
- 【Golang】字符串首字母大小写转化
写在前面 在自动化过程中,我们用得最多的可能就是字符串的处理,熟悉Python的都知道在Python中要让一个字符串的首字母大写直接用capitalize就可以了,但是同样的事情在Golang中没有这 ...
- Java设计模式(五)——适配器模式
先举一个例子解释一下生活中的适配器模式:公司老总要求工程部经理来汇报一下公司内部的消防设备使用和维护情况.接到通知后,工程部经理老宋找了专门负责消防设备统计的维护人员小王,请他调出了去年全年的维护记录 ...