Chinaunix首页 | 论坛 | 博客
  • 博客访问: 301640
  • 博文数量: 19
  • 博客积分: 2588
  • 博客等级: 少校
  • 技术积分: 730
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-12 13:11
文章分类

全部博文(19)

文章存档

2022年(11)

2013年(3)

2012年(1)

2011年(2)

2008年(2)

我的朋友

分类: Oracle

2008-10-17 09:46:09


文件:les1.rar
大小:2KB
下载:下载
阿里巴巴面里三個與開發有關的試題。
example 1:(not in/not exists + null)
  Create Table usertable(
       userid number,
       username varchar2(20)
  )
  /
  insert into usertable values(1,'user1');
  insert into usertable values(2,null);
  insert into usertable values(3,'user3');
  insert into usertable values(4,null);
  insert into usertable values(5,'user5');
  insert into usertable values(6,'user6');
  commit;
  Create Table usergrade (
    userid   number,
    username varchar2(20),
    grade number)
  /
  insert into usergrade values(1,'user1',90);
  insert into usergrade values(2,null,80);
  insert into usergrade values(7,'user7',80);
  insert into usergrade values(8,'user8',90);
  commit;

  語句1﹕ select count(*) from usergrade where username not in (select username from usertable );
  語句2﹕select count(*) from usergrade g where not exists
        (select null from usertable t where t.userid=g.userid and t.username=g.username);
  結果為: 語句1(  )        語句2( )

  答案
  A:0    B:1    C:2   D:3    E: null

example 2: (in/exists+rownum)
  drop table usertable;
  drop table usergrade;
 
  Create  table usertable (
   userid   number,
   username varchar2(20))
   /
   insert into usertable values(1,'user1');
   insert into usertable values(2,'user2');
   insert into usertable values(3,'user3');
   insert into usertable values(4,'user4');
   insert into usertable values(5,'user5');
   commit;
  
   Create table usergrade (
    username  varchar2(20),
    usergrade number)
    /
   insert into usergrade values('user9',90);
   insert into usergrade values('user8',80);
   insert into usergrade values('user7',80);
   insert into usergrade values('user2',90);
   insert into usergrade values('user1',100);
   insert into usergrade values('user1',80);
   commit;
 語句1﹕Select count(*) from usertable t1 where username in
         (select username from usergrade t2 where rownum <=1);
 語句2﹕Select count(*) from usertable t1 where exists
   (select 'x' from usergrade t2 where t1.username=t2.username and rownum <=1);
 結果為: 語句1(  )        語句2( )
   答案
   A:0    B:1    C:2   D:3

 
example 3:(關聯更新)
  Create table student_grade(
   id    number,
   grade number)
   /
   insert into student_grade values(1,50);
   insert into student_grade values(2,40);                   
   insert into student_grade values(3,70);
   insert into student_grade values(4,80);
   insert into student_grade values(5,30);
   insert into student_grade values(6,90);
   commit;
  
   Create table student_makeup(
   id number,
   grade number)
   /
   insert into student_makeup values(1,60);
   insert into student_makeup values(2,80);  
   insert into student_makeup values(5,60);
   commit;
  
   update student_grade s set s.grade=
    ( select t.grade from student_makeup t
       where s.id=t.id)
     commit;
   語句﹕select trade from student_grade where id=3;
       結果為()
   答案為﹕
    A:0    B:70   C:null   D:以上全不對。

--------------------------------------------------------------------
1.知識點︰not in/not exists+null
  關於where條件︰
     X AND Y: 只要X或者Y有一個是FALSE或者null的話,X AND Y返回FALSE。  
  關於null :
     一個NULL值意味著未知,因此,對一個NULL值的任何比較或操作也都是無效的,而任何返回NULL的測試也都被忽略。
  所以︰
      select 'true' from dual where 1 = null;
      select 'true' from dual where 1 != null;
      select 'true' from dual where 1 is null;
  以上比較不返回任何值。
      select 'true' from dual where null is null;
  null is null不是比較,而是說null 是個null,所以返回一行。
 
  IN︰
      in 后裡面的列表可以包括null,但是因為相當于用=依次比較,然後去or,true or null =true,所以他們是被忽視的(不理睬)。
      not in 實際上是用!=依次比較列表,然後去and,TRUE AND NULL = NULL。只要列表包括null值,就會返回FALSE(此where條件為FALSE)。
       所以,當not in后面是子查詢時, 只有保證select后面的字段有not null約束或暗示的時候才能使用。
      為了防止這種情況發生,可以在列表中阻止返回null︰
      not in (select a from t where a is not null);
      not in (select nvl(a,0) from t);

   對于in 和 exists的性能區別:
     如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,
   又有索引時使用exists。其實區分in和exists主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是exists,那么以外層表為驅動表,
  先被訪問,如果是IN,那么先執行子查詢,所以我們會以驅動表的快速返回為目標,那么就會考慮到索引及結果集的關係了

  對于not in 和 not exists的性能區別︰
      not in 只有當子查詢中,select 關鍵字后的字段有not null約束或者有這種暗示時用not in,另外如果主查詢中表大,子查詢中的表小但是記錄多,
   則應當使用not in,並使用anti hash join.如果主查詢表中記錄少,子查詢表中記錄多,並有索引,可以使用not exists,另外not in最好也可以用/*+ HASH_AJ */或者外連接+is null


2.知識點︰關聯更新
   Update student_grade s set s.grade =
    (select t.grade from student_makeup t where s.id=t.id)
        Where Exists ( Select 1 From student_makeup t Where s.id=t.id)
 
    update (select s.grade sgrade,t.grade tgrade from student_grade s,student_makeup t where s.id=t.id)
  set sgrade=tgrade;
   --ORA-01779: 無法修改對應非保留索引鍵表格的資料欄
   alter table student_makeup add primary key (id);
  
阅读(3754) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~