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. vue通过extend动态创建全局组件(插件)学习小记

    测试环境:nodejs+webpack,例子是看文章的,注释为自己的理解 创建一个toast.vue文件: <template> <div class="wrap" ...

  2. 程序设计-理解java继承-遁地龙卷风

    (0)写在前面 编程和现实世界是息息相关的,你是如何理解现实世界中的继承呢? 继承在编程中应理解为:对父类资源(本文只讨论方法)的使用,父类方法只提供类基本的功能,父类方法之间不存在调用关系. (1) ...

  3. 【先验知识归纳】Flask快速入门

    本文参考:快速入门 - Flask 0.10.1 文档 路由 Flask使用route修饰器来关联URL与程序函数: @app.route('/') def hello_world(): return ...

  4. P5290 [十二省联考2019]春节十二响

    题目地址:P5290 [十二省联考2019]春节十二响 骗分方法 如果你实在一点思路也没有,暴力都不会打,那么请考虑一下骗分. 方法一 输出所有 \(M\) 的和. 期望得分:0分. 实际还有5分 方 ...

  5. 【easy】202. Happy Number

    happy number Write an algorithm to determine if a number is "happy". A happy number is a n ...

  6. MySQL批量更新字段url链接中的域名

    1. 首先进行数据库备份 2. SQL语句 UPDATE 表名 SET 字段 = REPLACE(字段, '待更新的内容','替换值'); eg: UPDATE 98k_images SET url ...

  7. sass进阶—函数

    /*内置函数*/ /*1)常规的rgb,rgba函数*/$color:rgb(255,255,162);body{ color: $color; background-color:rgba($colo ...

  8. mysql group by 过滤字段 只能在SELECT 后面出现,不能写其他字段 报错解决 关键字 sql_mode=only_full_group_by

    1:报错  关键字 sql_mode=only_full_group_bymysql> select uuid,ip,count(*) from dbname_report.t_client_i ...

  9. [转]一个普通IT人的十年回顾---金旭亮

    金旭亮老师十年体会,很有收获.转自网络. 金旭亮于1989年与超级解霸的开发者梁肇新同时迈入广西大学的校门,却走了一条与其不同的路. 1994年起开始自学计算机专业本科课程,并开始编程,从未间断,迄今 ...

  10. 代码生成工具更新--快速生成Winform框架的界面项目

    在之前版本的代码生成工具Database2Sharp中,由于代码生成都是考虑Winform和Web通用的目的,因此Winform界面或者Web界面都是单独生成的,在工具中生成相应的界面后,复制到项目里 ...