• 再说exists 关键字,和inner join 差别大


    1.建表

    create table CUSTOMERS
    (
      CID   NUMBER not null,
      CNAME NVARCHAR2(50) not null
    )

    create table ORDERS
    (
      OID   NUMBER not null,
      ONAME VARCHAR2(50) not null,
      CID   NUMBER
    )

    2.添加数据

    select * from customers;

     CID       CNAME
    ---------- ---------------

       1          张三
       2          李四
       3          王五

    select * from orders;
     
           OID      ONAME            CID
    ---------- ------------------------ 

             1         订单1               1
             2         订单2               2
             3         订单3               2
             4         订单4               null                            
             5         订单5               4

    解释:customers 的主键cid ,是Orders 表中的外键,而orders 表的cid 可以为空,例如订单4的cid 不存在,

    另外需要注意的是 在orders表中不是每一条记录的cid ,在客户表customers表中都有对应的值,

    例如 订单5 的cid是4,在客户表customers中,就没有cid是4的记录

    3.exists 关键自在上述情景下的应用

    a.我要查询有订单号的客户信息

    select * from customers c where exists (select 1 from orders o where o.cid=c.cid);
     
           CID     CNAME
    ---------- ----------

             1        张三
             2        李四

    只有两条记录 ;

    解释 遍历customers的表的每一条记录的时候,把cid 的值 ,传给o.cid, 然后看在orders表中是否存在记录,如果存在 条件为 true,

    这样就返回了一条记录。

    当在customers 遍历 cid 是1,2 custmers 都有对应的cid,而遍历cid 是3的时候 customers 表中没有对应的记录,返回false

    所以一共返回两条记录。

    --------------------------------------------

    b. 查询有客户id 的订单信息


    SQL>  select * from orders o where exists (select 1 from customers c where c.cid=o.cid) order by 1;
     
           OID ONAME                                                     CID
    ---------- -------------------------------------------------- 

             1   订单1                                                       1
             2   订单2                                                       2
             3   订单3                                                       2

    解释:查询订单oid 是1,2,3的时候 customers表中都有对应的客户,

    而查询到oid 是4 ,5的时候 cid号或者为空,或者在customers表中不存在这条记录,

    所以只返回三条记录

    4.使用inner join 或“=” 连接两个表的查询

    select * from customers c inner join orders o on c.cid = ocid;

       CID   CNAME                    OID        ONAME             CID
    ---------- ------------------------------------- ----------
         1      张三                      1            订单1                1
         2     李四                       2             订单2               2
         2     李四                       3             订单3               2

    查询出来的是3条数据,

    和 select * from customers c , orders o where c.cid = o.cid; 查询结果一样

       CID   CNAME                   OID ONAME            CID

        1      张三                         1 订单1                  1
        2      李四                         2 订单2                  2
        2      李四                         3 订单3                  2

    -----------------------------

    差别 :你们是否以为 select c.* from customers c where exists (select 1 from orders o where o.cid=c.cid);

    和 select c.* from customers c inner join orders o on c.cid=o.cid 的结果集是一样的?

    答案是不一样,前者用exists 关键词的时候 返回两条记录,

           CID   CNAME
    ---------------------------

             1     张三
             2     李四

    而后者返回了3条记录,

    SQL> select c.* from customers c inner join orders o on c.cid=o.cid ;
     
           CID CNAME
    ---------- --------

             1 张三
             2 李四
             2 李四

    当遍历到cid 是2 李四的时候,orders 表中有两条记录和它对应,

    一条是 cid 2,cname 是李四 ,oid 是2 ,另一条是 cid 2,cname 是李四 ,oid 是3, 我们只不过是select 的时候 只显示出了cid,和cname,可是查却查出来3条记录,

    就算cid 和cname重复了吧,可oid 没有重复

      CID CNAME       OID   ONAME        CID

       2 李四               2     订单2             2
       2 李四               3     订单3             2 

    -------------------------------------------------------

    或许有一些初学者说不就重复几条数据嘛 这不算什么,可如果在统计分析的时候 一条数据就影响到统计的准确性,如果一条数据的某个值是1000000,

    我有对这个字段的所有的字段值求和,而就多了这么一条数据,就多加了10000000,你说影响结果有多大?认真起来大家

  • 相关阅读:
    【腾讯Bugly干货分享】微信Tinker的一切都在这里,包括源码(一)
    【腾讯Bugly干货分享】iOS10 SiriKit QQ适配详解
    【腾讯Bugly干货分享】安卓单元测试:What, Why and How
    【腾讯Bugly干货分享】Android Linker 与 SO 加壳技术
    【腾讯优测干货分享】Android内存泄漏的简单检查与分析方法
    【腾讯Bugly经验分享】程序员的成长离不开哪些软技能?
    【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
    从零开始安装Hadoop视频教程
    如何在MAC机器中实现移动设备WiFI上网(没有专门的无线路由器的情况)
    Alfresco安装与配置图解
  • 原文地址:https://www.cnblogs.com/qylbg/p/3188542.html
Copyright © 2020-2023  润新知