首先,一般Oracle从右向左解析条件,b.name not in就先过滤了b表中相关内容,和a表外连接后除了有两条相等的(a表中也有的)外,再填补了a表所有内容,对b表没有的字段置为空;a.name not in过滤了a表,再进行外连接

解决方案 »

  1.   

    ern,如果按"b.name not in就先过滤了b表中相关内容,和a表外连接后除了有两条相等的(a表中也有的)外,再填补了a表所有内容"来解释,执行完第一段代码后应该显示a表的所有内容,可他并没显示啊.麻烦再解释解释~~~~~~~~~~~~~~
      

  2.   

    首先执行from songyh.worker a, songyh.workerskill b 语句,相当于告诉数据库中a表中的每一条数据要跟b中的每一条数据作连接。 具体执行时,从a表中选出一条记录,然后根据b表中的一条记录按着连接条件连接。 连好的记录再根据where的条件判断是否要显示。判断时就有一个先后的问题了,oracle数据库从where条件的最后条件开始,即先根据a.name not in
      (select name from songyh_worker_skill where skill='Smithy')  判断, 然后再根据
    a.name=b.name(+)判断, 当然,如果不满足第一条,就pass了, 不必再看第二条了。这样一次判断一个“预连接”的笛卡尔积,-----最后得出结果。
      

  3.   

    绝对没反!!!如果没有代表性,我也就不这样问了!!
    请问如何看执行计划啊???
    偶刚接触oracle,呵呵!
    高手继续指教啊!!!
      

  4.   

    对NULL理解的问题:
    肯定是a.name=b.name(+)先执行,但是第一个用b.name去not in,连接后b.name某些记录为null,而null作为任何条件判断是无意义的.这些记录肯定被弃掉.
    连接后a.name肯定有值,所以结果记录多.
      

  5.   

    你可以把你的sql语句拆开来执行
    select a.name,a.age,a.lodging ,b.skill,b.ability from songyh_worker a,
     songyh_worker_skill  b   where   a.name=b.name(+);select a.name,a.age,a.lodging ,b.skill,b.ability from songyh_worker a,
     songyh_worker_skill  b where a.name not in(select name from songyh_worker_skill where skill='Smithy'); a.name=b.name(+) 其实是取出了 a.name 中全部的的数据记录就第一条sql b.name not in 其实就是限定了 b.name=Adah Talbot,Elbert Talbot,Helen Brandt,Wilfred Lowell 在这条sql 中其实 a.name=b.name(+) 就等于 a.name=b.name
    也就是a.name=Adah Talbot,Elbert Talbot,Helen Brandt,Wilfred Lowell第二条 sql 是后面的 not in 限制了 a.name 的取值的范围 a.name=b.name(+) 只是限制了
    数据的冗余数据不同 但理论应该是一样的 :
    ops$lg\[email protected] >select * from t1;         N
    ----------
             1
             2ops$lg\[email protected] >select * from t2;        N2
    ----------
             1
             3
              -- 这是我把第一个 sql 语句分开执行的语句
    ops$lg\[email protected] >select t1.n,t2.n2 from t1,t2 where t1.n=t2.n2(+);  《语句1》         N         N2
    ---------- ----------
             1          1
             2ops$lg\[email protected] >select t1.n,t2.n2 from t1,t2 where t2.n2 not in(3); 《语句2》         N         N2
    ---------- ----------
             1          1
             2          1ops$lg\[email protected] >select t1.n,t2.n2 from t1,t2 where t1.n=t2.n2(+) and t2.n2 not in(3);  
      -- 在这个语句中应该是上面两个语句的交集 所以只有一条结果         N         N2
    ---------- ----------
             1          1
    你的第2条 sql 道理类似的
      

  6.   

    我认为第一个语句执行b.name not in
      3* (select name from songyh_worker_skill where skill='Smithy')
    时,由于一些name在第二个表中没有对应的,如Bart Sarjeant  也就是说b.name 为null,所以,就被pass了,
    所以,第一个表里的数据比第二个少 
    不知道对吗?我这样理解
      

  7.   

    那么外连接的作用不是失效了吗?也就是说oracle先处理的是(外)连接,然后再处理条件(判断)吗?是这样吗?
    如果要提高查询效率,应该是先判断,然后在进行连接啊?而不应该是先连接在判断啊?兄弟们继续探讨啊!!
    响应的人太多了,分不够了!呵呵!
      

  8.   

    这要看你如何的写法。
    这种旧式的外连接(+),在加条件时,容易造成歧义。
    9i后,ORACLE建议用LEFT JOIN的写法了。
      

  9.   

    太乱了,没仔细看,不过插一句
    用not in 时,如果 字段没有建唯一索引,查询结果可能会不准确
      

  10.   

    marinedalian(红袖添香) ( )
    首先执行from songyh.worker a, songyh.workerskill b 语句,相当于告诉数据库中a表中的每一条数据要跟b中的每一条数据作连接。 具体执行时,从a表中选出一条记录,然后根据b表中的一条记录按着连接条件连接。 连好的记录再根据where的条件判断是否要显示。判断时就有一个先后的问题了,oracle数据库从where条件的最后条件开始,即先根据a.name not in
      (select name from songyh_worker_skill where skill='Smithy')  判断, 然后再根据
    a.name=b.name(+)判断, 当然,如果不满足第一条,就pass了, 不必再看第二条了。这样一次判断一个“预连接”的笛卡尔积,-----最后得出结果。drabit(square)
      对NULL理解的问题:
    肯定是a.name=b.name(+)先执行,但是第一个用b.name去not in,连接后b.name某些记录为null,而null作为任何条件判断是无意义的.这些记录肯定被弃掉.
    连接后a.name肯定有值,所以结果记录多.
    楼主 我觉得答案就是这两位仁兄的综合了 呵呵 学习了很多东西啊啊!