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. 查不到opencv版本的问题

    检查opencv版本:pkg-config --modversion opencv 前两天卸载了opencv3.0,想重装2.4版本.安装是没有问题,但现在查不到opencv版本,程序也编译不通过. ...

  2. ch03 课下作业——缓冲区溢出漏洞实验

    一.实验简介: 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭 ...

  3. Linux 一 些常用的命令

    查看当前系统JAVA的安装路径: echo $JAVA_HOME: 查看内核版本: uname -a ubuntu的防火墙 关闭:ufw disable开启:ufw enable 卸载了 iptabl ...

  4. day03 数据类型与运算符

    今日内容: 1.变量及常量的命名规范 2.与用户的交互 3.字符串的格式化输出 4.基本的数据类型 5.运算符 6.注释 今日重点: 1.变量及常量的命名规范 (1)强制规范[如果违反会报错] 1&g ...

  5. LNMP一键包安装后解决MySQL无法远程连接问题

    MySQL/MariaDB无法远程连接,如何开启? 1,没有给root对应的权限 -- @'192.168.1.123'可以替换为@‘%’就可任意ip访问 mysql> GRANT ALL PR ...

  6. Misc杂项隐写题writeup

    MISC-1 提示:if you want to find the flag, this hint may be useful: the text files within each zip cons ...

  7. 【原创】大叔经验分享(26)hive通过外部表读写elasticsearch数据

    hive通过外部表读写elasticsearch数据,和读写hbase数据差不多,差别是需要下载elasticsearch-hadoop-hive-6.6.2.jar,然后使用其中的EsStorage ...

  8. RabbitMQ的Java API编程

    1.创建Maven工程,pom.xml引入依赖: <dependency> <groupId>com.rabbitmq</groupId> <artifact ...

  9. PDF怎样添加注释,PDF文件添加注释的方法

    Word文件跟纸质文件想要添加注释相信大家都知道该怎么添加,那么现在也使用频率挺高的PDF格式的文件要怎么添加注释呢?添加注释的方法有什么呢?有许多的小伙伴们都想知道吧,今天小编就来跟大家分享一下,想 ...

  10. windows无法安装msi文件

    命令提示符(管理员身份运行): 输入:msiexec /i e:\spark\scala-2.11.12.msi 其中e:\spark\scala-2.11.12.msi:就是安装文件的位置.