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 建表语句*/ ...
随机推荐
- Visual Status各个版本官网下载
网址:https://www.visualstudio.com/zh-hans/vs/older-downloads/
- 【Git安装】centos安装git
1 yum install git 安装后的默认存放地点/usr/bin/git
- jquery 浏览器打印
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- Leetcode ——Partition Equal Subset Sum
Question Given a non-empty array containing only positive integers, find if the array can be partiti ...
- hdoj-1005-Number Sequences
题目:Number Sequences 代码: #include<stdlib.h> #include<iostream> #include<cstdio> #in ...
- JAVA类和对象创建
面向对象 学习目标: 理解面向对象的编程思想 理解类与对象的关系 如何创建类与对象 方法重载 一:什么是面向对象编程(OOP) 面向对象编程(Object Oriented Programming,O ...
- input聚焦后光标移动至末尾
var valSrc=obj.val();obj.val(“”).focus().val(valSrc);
- VSAN Cluster Failed
failed message:AdVanced vSAN configuration in syncChecks if all of the hosts in a vSAN cluster have ...
- 图片保存到数据库以及C#读取图片
图片保存到数据库,如果是sqlserver就是Image类型,如果保存到Oracle就是blob类型,在c#中相对应的就是byte[]类型,同时只需要对读出的数据强制转换就行(byte[])objec ...
- every day a practice —— morning
In 25 years, Panda Express has transformed from a single restaurant in a southern California mall to ...