1. 程式人生 > >oracle資料庫之多表聯接查詢(一)

oracle資料庫之多表聯接查詢(一)

--此文章可以作為sql指令碼直接執行

/*

  建表以及插入相關資料,為後面的查詢做準備工作

*/

--建學生資訊表
create table studentinfo(
  stuid  int  primary key,
  sname  varchar(10) not null,
  cid    int not null,
  address varchar(20)
);
--建班級表
create table classes(
  cid   int primary key ,
  cname varchar2(10)
);
--建考試資訊表
create table exam(
  eid int  primary key,
  stuid int not null,
  coursename varchar(20) not null,
  score float
);
--加上外來鍵約束     外來鍵約束在表內不好加,因為要可慮建立表的先後順序,放在後面一起加就可以不考慮此問題
alter table studentinfo add  constraint fk_cid foreign key (cid) references  classes(cid);
alter table exam add  constraint fk_stuid foreign key(stuid) references  studentinfo(stuid);

--必須先插入classes表的資料,否則studentinfo表中的外來鍵找不到參照的物件
insert into classes values (1,'0901');
insert into classes values (2,'0902');
insert into classes values (3,'0903');

create sequence seq_stuid ;
insert into studentinfo values(seq_stuid.Nextval,'zhangsan',1,'hnzz');
insert into studentinfo values(seq_stuid.Nextval,'lisi',1,'hncs');
insert into studentinfo values(seq_stuid.Nextval,'wangwu',2,'hncd');
insert into studentinfo values(seq_stuid.Nextval,'zhaoliu',2,'hndd');
insert into studentinfo values(seq_stuid.Nextval,'zhudao',3,'hnyy');
insert into studentinfo values(seq_stuid.Nextval,'david',3,'hnyy');

create sequence seq_eid ;
insert into exam values(seq_eid.Nextval,1,'java',80);
insert into exam values(seq_eid.Nextval,2,'java',59);
insert into exam values(seq_eid.Nextval,3,'java',67);
insert into exam values(seq_eid.Nextval,5,'oracle',99);
insert into exam values(seq_eid.Nextval,6,'oracle',100);

select * from classes ;
select * from studentinfo ;
select * from  exam ;

/*  開始今天的內容  */

--內聯查詢

----題目:請查詢出所有參加了考試的同學的姓名,班級,考試科目和考試成績

select sname as 姓名,cname as 班級,coursename as 科目,score as 分數    --要查詢什麼就select什麼,最好取上別名,更容易理解查詢結果

from studentinfo s inner join exam e     --從studentinfo表 內聯接 exam表     

on s.stuid = e.stuid                     --on   後面接條件(兩張表聯接的資料對應方式)    取表別名可以省寫一些程式碼

inner join classes c                    

on c.cid=s.cid ;                         --這種聯接可以一直聯接下去    前提是表之間有資料的對應       


--下面我們將進行聯接的兩個表交換下位置      

select sname as 姓名,cname as 班級,coursename as 科目,score as 分數   

from exam e inner join studentinfo s      

on s.stuid = e.stuid                    

inner join classes c                     

on c.cid=s.cid ;

--->查詢結果無變化     內聯查詢跟表的位置無關

--->分析:內聯查詢是   從左邊的表往右邊的表查詢能匹配的記錄,無匹配的記錄行不顯示


--外聯查詢  可以查詢出某些找不到對應值的行    左外聯和右外聯

--左外聯  左邊的表中的行數全部保留  (從左邊的行往右邊找對應行)  無匹配記錄的行也會顯示,顯示資料為空

select sname ,coursename ,score

from studentinfo s left join exam e on s.stuid =e.stuid ;

--右外聯  右邊的表中的行數全部保留  (從右邊的行往左邊找對應行)

select sname ,coursename ,score

from studentinfo s right join exam e on s.stuid =e.stuid ;

--可以找出沒有去參加考試的人

select sname ,coursename ,score

from studentinfo s left join exam e on s.stuid =e.stuid

where score is null ;


--全外聯   兩邊表的行資料都能夠儲存    會顯示無對應記錄的行

select sname ,coursename ,score

from studentinfo s full join exam e on s.stuid =e.stuid ;


--交叉聯接     查詢結果  左邊表的每一行都對應一次右邊表的行   

----左邊有5行   右邊有3行     查詢結果是  5*3=15行

select sname ,coursename ,score

from studentinfo s cross join exam e  ;

--下面的查詢和交叉聯接查詢效果一樣

select sname ,coursename ,score

from studentinfo s , exam e  ;


create table shu1(
num1 int
);

insert into shu1 values (0);
insert into shu1 values (1);
insert into shu1 values (2);
insert into shu1 values (3);
insert into shu1 values (4);
insert into shu1 values (5);
insert into shu1 values (6);
insert into shu1 values (7);
insert into shu1 values (8);
insert into shu1 values (9);

--交叉聯接的應用    

--生成彩票號碼的表  還用到了自聯接  這裡模擬的是簡單的,只有3位數的彩票,不過思路是這樣的

create table caipiao   --oracle中一種特殊的建表方式----》create table 表名 as select ...  將查詢到的資料直接插入到新生成的表中  

as

select a.num1 as a,b.num1 as b,c.num1 as c   --新建的表的列名就是這裡取的別名   這裡新建表的列名就是 a,b,c

from shu1 a cross join shu1 b cross join shu1 c;


select * from caipiao ;

select count(*) as 彩票號碼總數 from caipiao ;


--求奇數列的和    

create table test

as

select shu1.*,rownum as hangshu

from shu1 ;


select sum(num1) as 奇數列和 from test

where mod(hangshu,2) = 1 ;   --mod(a,b)   求 a 模 b 的函式