1、测试数据:

SQL> select * from dept;
 
DEPTNO DNAME          LOC
------ -------------- -------------
     10 ACCOUNTING     NEW YORK
     20 RESEARCH       DALLAS
     30 SALES          CHICAGO
     40 OPERATIONS     BOSTON
 
SQL> select * from emp;
 
EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
  7369 SMITH      CLERK      7902 1980/12/17     800.00               20
  7499 ALLEN      SALESMAN   7698 1981/2/20     1600.00    300.00     30
  7521 WARD       SALESMAN   7698 1981/2/22     1250.00    500.00     30
  7566 JONES      MANAGER    7839 1981/4/2      2975.00               20
  7654 MARTIN     SALESMAN   7698 1981/9/28     1250.00   1400.00     30
  7698 BLAKE      MANAGER    7839 1981/5/1      2850.00               30
  7782 CLARK      MANAGER    7839 1981/6/9      2450.00               10
  7788 SCOTT      ANALYST    7566 1987/4/19     3000.00               20
  7839 KING       PRESIDENT       1981/11/17    5000.00               10
  7844 TURNER     SALESMAN   7698 1981/9/8      1500.00      0.00     30
  7876 ADAMS      CLERK      7788 1987/5/23     1100.00               20
  7900 JAMES      CLERK      7698 1981/12/3      950.00               30
  7902 FORD       ANALYST    7566 1981/12/3     3000.00               20
  7934 MILLER     CLERK      7782 1982/1/23     1300.00               10
 
14 rows selected

2、左连接测试

SQL> select
e.empno, e.ename, e.deptno, d.deptno, d.dname
   3  from scott.emp e left join scott.dept d on e.deptno = d.deptno and e.deptno != 20 and d.deptno != 30;

EMPNO ENAME                  DEPTNO     DEPTNO DNAME
---------- ------------------------------ ---------- ---------- ------------------------------------------
       7934 MILLER                  10         10 ACCOUNTING
       7839 KING                   10         10 ACCOUNTING
       7782 CLARK                  10         10 ACCOUNTING
       7900 JAMES                  30
       7844 TURNER                  30
       7698 BLAKE                  30
       7654 MARTIN                  30
       7521 WARD                   30
       7499 ALLEN                  30
       7902 FORD                   20
       7876 ADAMS                  20
       7788 SCOTT                  20
       7566 JONES                  20
       7369 SMITH                  20

14 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3387915970

---------------------------------------------------------------------------
| Id  | Operation       | Name | Rows  | Bytes | Cost (%CPU)| Time      |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    14 |   364 |    7  (15)| 00:00:01 |
|*  1 |  HASH JOIN OUTER   |      |    14 |   364 |    7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| EMP  |    14 |   182 |    3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| DEPT |    3 |    39 |    3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("E"."DEPTNO"="D"."DEPTNO"(+))
        filter("E"."DEPTNO"<>CASE  WHEN ("D"."DEPTNO"(+) IS NOT NULL)
           THEN 20 ELSE 20 END )
    3 - filter("D"."DEPTNO"(+)<>30)

Statistics
----------------------------------------------------------
       0  recursive calls
       0  db block gets
      13  consistent gets
       0  physical reads
       0  redo size
        1082  bytes sent via SQL*Net to client
     524  bytes received via SQL*Net from client
       2  SQL*Net roundtrips to/from client
       0  sorts (memory)
       0  sorts (disk)
      14  rows processed

-- 结论:left join 仅有on子句
-- 过滤条件对左表无效;

-- on子句过滤条件仅对右表生效;
-- 对于右表,过滤条件在连接之前生效(即先过滤,后连接);
-- 对于左表,过滤条件在连接之后生效(即先连接,后过滤)。
     
SQL> select
e.empno, e.ename, e.deptno, d.deptno, d.dname
   3  from scott.emp e left join scott.dept d on e.deptno = d.deptno where e.deptno != 20 and d.deptno != 30;

EMPNO ENAME                  DEPTNO     DEPTNO DNAME
---------- ------------------------------ ---------- ---------- ------------------------------------------
       7782 CLARK                  10         10 ACCOUNTING
       7934 MILLER                  10         10 ACCOUNTING
       7839 KING                   10         10 ACCOUNTING

Execution Plan
----------------------------------------------------------
Plan hash value: 844388907

----------------------------------------------------------------------------------------
| Id  | Operation             | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |           |     9 |   234 |     6    (17)| 00:00:01 |
|   1 |  MERGE JOIN             |           |     9 |   234 |     6    (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     3 |    39 |     2     (0)| 00:00:01 |
|*  3 |    INDEX FULL SCAN         | PK_DEPT |     3 |       |     1     (0)| 00:00:01 |
|*  4 |   SORT JOIN             |           |     9 |   117 |     4    (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | EMP     |     9 |   117 |     3     (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("D"."DEPTNO"<>30 AND "D"."DEPTNO"<>20)
    4 - access("E"."DEPTNO"="D"."DEPTNO")
        filter("E"."DEPTNO"="D"."DEPTNO")
    5 - filter("E"."DEPTNO"<>20 AND "E"."DEPTNO"<>30)

Statistics
----------------------------------------------------------
       0  recursive calls
       0  db block gets
      10  consistent gets
       0  physical reads
       0  redo size
     916  bytes sent via SQL*Net to client
     524  bytes received via SQL*Net from client
       2  SQL*Net roundtrips to/from client
       1  sorts (memory)
       0  sorts (disk)
       3  rows processed

-- 结论:where子句过滤
-- 过滤条件对于左右表都有效;
-- 对于右表,过滤条件在连接之前生效(即先过滤,后连接);
-- 对于左表,过滤条件在连接之前生效(即先过滤,后连接);
-- 对于左连接,右表过滤字段出现在连接条件中,左连解会变成内连接。

3、以下SQL自行测试,可验证以上结论:

select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d join scott.emp e on e.deptno = d.deptno where e.deptno != 20 and d.deptno != 30;
  
select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d join scott.emp e on e.deptno = d.deptno where d.deptno != 30;
  
select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d join scott.emp e on e.deptno = d.deptno where e.deptno != 20;

select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d left join scott.emp e on e.deptno = d.deptno where e.deptno != 20 and d.deptno != 30;
  
select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d left join scott.emp e on e.deptno = d.deptno where d.deptno != 30;
  
select
e.empno, e.ename, e.deptno, d.deptno, d.dname
from scott.dept d left join scott.emp e on e.deptno = d.deptno where e.deptno != 20;

SQL语句之on子句过滤和where子句过滤区别的更多相关文章

  1. SQL语句中count(1)count(*)count(字段)用法的区别

    SQL语句中count(1)count(*)count(字段)用法的区别 在SQL语句中count函数是最常用的函数之一,count函数是用来统计表中记录数的一个函数, 一. count(1)和cou ...

  2. SQL语句中count(1)count(*)count(字段)用法的区别(转)

    SQL语句中count(1)count(*)count(字段)用法的区别 在SQL语句中count函数是最常用的函数之一,count函数是用来统计表中记录数的一个函数, 一. count(1)和cou ...

  3. SQL语句中order_by_、group_by_、having的用法区别

    order by 从英文里理解就是行的排序方式,默认的为升序. order by 后面必须列出排序的字段名,可以是多个字段名. group by 从英文里理解就是分组.必须有“聚合函数”来配合才能使用 ...

  4. Sql语句中的truncate,delete,drop的区别

    相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 不同点: 1. truncate 和 delete 只删除数据不删除表的结构(定义) drop 语句 ...

  5. sql语句中 left join,right join,inner join 的区别

    看到了sql,发现好久没写sql甚是想念哈哈哈哈,好多当时学的东西都忘了,当时总结的好多的文档也怎么都找不到了..... 言归正传,找到了一张图感觉描述的还挺清晰,先贴图,再说说自己的理解. 1.LE ...

  6. sql语句中 int(1)与int(10)有什么区别?资深开发竟然能理解错

    过完春节该投入战斗了,上班第一天发现了一个挺有意思的知识点给大家分享一下:一直以来的的误区我们都认为了int后面的跟的数字为最大显示宽度会对后面插入的参数会有限制,其实倒不是这样的 # 困惑 最近遇到 ...

  7. SQL 语句中的in、find_in_set、like的区别

    1.in查询相当于多个or条件的叠加,例如: select * from user where user_id in (1,2,3);等效于select * from user where user_ ...

  8. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  9. SQLServer 学习笔记之超详细基础SQL语句 Part 11

    Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 10------------------- DECLARE @myavg ...

  10. LINQ to SQL语句大全

    LINQ to SQL语句大全     LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...

随机推荐

  1. radio日志sim卡信号状态分析

    logcat -b radio日志 // 接着将slot 0主卡置为false,将slot 1设置为true 08-09 11:24:40.335 2565 3243 D RILJ : [4820]& ...

  2. Web从入门到放弃<8>

    Ref: Cameron D. - HTML5, JavaScript and jQuery (Programmer to Programmer) - 2015 http://www.runoob.c ...

  3. 新手如何理解JS面向对象开发?

    今天有时间讲讲我对面向对象的理解跟看法,尽量用通俗的语言来表达,多多指教! 如今前端开发已经越来越火了,对于前端开发的要求也是越来越高了,在面试中,经常有面试官会问:你对JS面向对象熟悉吗? 其实,也 ...

  4. keepalive半同步双主一从

    ip地址如下: 192.168.20.201 redis01 主 192.168.20.202 redis02 主 192.168.20.203 redis03 从 192.168.20.205 vi ...

  5. 【算法】【python实现】二叉搜索树插入、删除、查找

    二叉搜索树 定义:如果一颗二叉树的每个节点对应一个关键码值,且关键码值的组织是有顺序的,例如左子节点值小于父节点值,父节点值小于右子节点值,则这棵二叉树是一棵二叉搜索树. 类(TreeNode):定义 ...

  6. PYTHON-模块 re subprocess

    # re 正则表达式 ****** 学符号 单字符 范围 重复 位置 分组 精准 写不出来百度去# http://www.cnblogs.com/Eva-J/articles/7228075.html ...

  7. 在CentOS 7上部署Ghost博客

    作者:waringid 一.简介 跟静态博客不同的是,Ghost 这种轻量级的动态博客,有一个管理后台,可以直接写作和管理博客.本质上,跟 WordPress 是相通的,只是 Ghost 搭建在 No ...

  8. spring官网上下载历史版本的spring插件,springsource-tool-suite

    spring官网下载地址(https://spring.io/tools/sts/all),历史版本地址(https://spring.io/tools/sts/legacy). 注:历史版本下载的都 ...

  9. Python_多线程threading模块

    python 在执行的时候会淡定的在CPU上只允许一个线程运行,故Python在多核CPU的情况下也只能发挥出单核的功能,其中的原因:gil锁 gil 锁 (全局解释器锁):每个线程在执行时都需要先获 ...

  10. 利用反射获取数据列+emit生成属性+单例模式

    1:IDictionary<string,string > 可以存储数据,将拼接的sql可以存储到这里下次可以使用 定义自定义属性表和列 typeof(T).GetCustomAttrib ...