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. sublime代码整理

    1. 2.输入: { "keys":["ctrl+shift+z"], (快捷键自定义,只要不冲突就可以了) "command":" ...

  2. Windows caffe 跑mnist实例

       一. 装完caffe当然要来跑跑自带的demo,在examples文件夹下. 先来试试用于手写数字识别的mnist,在 examples/mnist/ 下有需要的代码文件,但是没有图像库. mn ...

  3. Vertx eventbus模块解析

    eventbus 事件總線 協議棧 TCP分包,粘包解決採用方案: 消息定长(定義消息体總长度),消息分为消息头和消息体 dataType bytes description int 4 包体总大小 ...

  4. 编辑技巧分享如何给PDF添加注释

    纸质的文件想要添加注释就直接拿笔在上面添加就好了,那么电子文件要怎么添加注释呢,今天小编就以我们现在经常使用到的PDF文档来为大家分享怎么添加注释.   1. 我们需要在百度中搜索并下载并安装一款PD ...

  5. 你好!酷痞Coolpy 之 Linux篇

    欢迎你进入酷痞的物联网世界.这里有着自由的空气和自然的气息.接下来我将告诉你如果一步步建立一个自己专属的物联网平台. 由于目前的酷痞的官方域名还没有通过备案所以现在用临时域名解说本说明. 最终酷痞的官 ...

  6. 一个div实现白眼效果

    巧妙利用border和background-clip   <div class="eye"></div> .eye{ width:150px; height ...

  7. 如何写一个Js上传图片插件。

    项目里面需要一个上传图片的插件,找了半天没有找到满意的,算了 不找了,自己写一个吧,顺便复习一下js方面的知识.完成之后效果还不错,当然还要继续优化,源码在最后. 介绍一种常见的js插件的写法 ; ( ...

  8. [wordpress]更新插件时,免去FTP操作

    我们先进入服务器 先找到wordpress配置文件wp-config.php,用locate命令寻找文件所在路径. sudo updatedb locate wp-config.php 然后cd到改路 ...

  9. Docker操作笔记(三)数据管理

    数据管理 一.数据卷 数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性: 数据卷 可以在容器之间共享和重用 对 数据卷 的修改会立马生效 对 数据卷 的更新,不会 ...

  10. Django与supervisor 管理进程

    1.前言 在Django项目中,我们需要用到一些独立于Django框架外的脚本.这样一些脚本可能需要独立的持续运行,且具有很强的可维护性,这个时候supervisor就可以排上用场了. 基于pytho ...