再说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,你说影响结果有多大?认真起来大家

 

posted @ 2013-07-13 21:05  令狐冲之12  阅读(1960)  评论(0编辑  收藏  举报