一、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运算符是有优先级的更多相关文章

  1. MySQL中使用INNER JOIN来实现Intersect并集操作

    MySQL中使用INNER JOIN来实现Intersect并集操作 一.业务背景 我们有张表设计例如以下: CREATE TABLE `user_defined_value` ( `RESOURCE ...

  2. 关于MySQL中的left join、on、where的一点深入

    原文地址:http://www.oschina.net/question/89964_65912?sort=default&p=3#answers 即使你认为自己已对 MySQL 的 LEFT ...

  3. 使用Mysql中的concat函数或正则匹配来快速批量生成用于执行的sql语句

    背景介绍 今天需要给一张表里面补数据,需要按照行的维度进行update,如果是个别数据那么直接写update语句就可以了,但是场景要求的是将整表的数据进行update,要实现这个需求就不能只靠蛮力了, ...

  4. Mysql高手系列 - 第7篇:玩转select条件查询,避免踩坑

    这是Mysql系列第7篇. 环境:mysql5.7.25,cmd命令中进行演示. 电商中:我们想查看某个用户所有的订单,或者想查看某个用户在某个时间段内所有的订单,此时我们需要对订单表数据进行筛选,按 ...

  5. oracle 在xml中批量插入,批量修改及多组条件查询

    最近公司用ibatis开发项目,本来可以用存储过程处理批量插入,批量修改及多组条件查询:但由于使用模块相对较小,暂时就在xml中配置,以前没有在xml做过类似处理,有必要记录一下:好了,代码如下: & ...

  6. MySQL中日期与字符串相互转换,并进行日期比较查询

    技术交流群:233513714 1.日期无需转换查询(日期在数据库中的类型为字符串) select * from day where dateTime > '2016-03-15' 2.使用da ...

  7. 多条件查询(php+mysql) 租房子例子

    <body> <?php //多条件 $tiaojian2= " 2=2 "; $attr2 = ""; //判断区域 if(!empty($ ...

  8. MySQL中链接查询inner join与left join使用

    连接查询其实就是对两个表记录做笛卡尔乘积.如果不指定连接条件的话,则会对每行都做笛卡尔乘积,这样最后返回的结果树就会是两个表记录数的乘积:如果指定则,则仅对符合列条件的行进行笛卡尔乘积,并返回结果.在 ...

  9. mysql中的几种join 及 full join问题

    [注意]:Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+ union+右外连接实现 初始化SQL语句:   /*join 建表语句*/   ...

随机推荐

  1. 网站精准查询IP

    分享一些网站能精准查询IP的 https://www.chaidu.com/App/Web/IP/ http://www.ipip.net/ip.html http://www.hao7188.com ...

  2. Python3基础 list 查看filter()返回的对象

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  3. git如何生成指定两个commit之间的补丁

    答:git format-patch <base commit id>..<latest commit id> 如git log输出以下内容: commit 2222222 y ...

  4. sql 题目

    1.自增列 通用: ) from table b where b.sid<a.sid) ,* from table a; ,),* from ... 第二个已经有主键自增列的就不可以用了 还有就 ...

  5. IDEA快捷键复习使用

    https://www.jetbrains.com/help/idea/meet-intellij-idea.html 快捷键可以极快地进行代码编辑整理,在IDEA的快捷键中,除了有几个好像特别难按之 ...

  6. java对象在内存的大小

    前言 一直以来,对java对象大小的概念停留在基础数据类型,比如byte占1字节,int占4字节,long占8字节等,但是一个对象包含的内存空间肯定不只有这些. 假设有类A和B,当new A()或者n ...

  7. 详解一下 javascript 中的比较

    翻译自:http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 在JS中的关系比较(Relational Comparison)运算,指的 ...

  8. python 判断字符串是否以数字结尾

    import re def end_num(string): #以一个数字结尾字符串 text = re.compile(r".*[0-9]$") if text.match(st ...

  9. jenkins 工作空间的目录

    /usr/share/tomcat7/.jenkins/workspace/

  10. Meta referrer标签的简要介绍

    在某些情况下,出于一些原因,网站想要控制页面发送给 server 的 referer 信息的情况下,可以使用这一 referer metadata 参数. 参数 referer 的 metedata ...