1. 程式人生 > 資料庫 >資料庫實驗之多表查詢與外來鍵

資料庫實驗之多表查詢與外來鍵

一、需求

利用前2次實驗中的【學生表】和【成績表】進行如下操作;
【學生表】結構如下:
序號,int型別,自增;主鍵;
學號,char(10);唯一索引;
姓名:varchar(20);
性別:列舉型別,取值為男或女;
【學生表】資料如下:
(1,101,張三,男)
(2,102,李四,女)
(3,103,王五,男)
【成績表】結構如下:
序號,int型別,自增;主鍵;
學號,char(10);
課程號:char(10);
成績:int;
績點:dec(3,1);
【成績表】資料如下:
(1,101,201,80,0)
(2,101,202,75,0)
(3,101,203,84,0)
(4,102,201,89,0)
(5,102,202,90,0)

(6,102,203,65,0)
(7,104,201,89,0)
(8,104,202,69,0)
多表:

  1. 查詢每個同學的201課程的成績,顯示如下欄位資訊:學號、姓名、課程號、成績、績點;
  2. 查詢每個同學的201課程的成績(包括沒有參加201課程考試的同學),顯示如下欄位資訊:學號、姓名、課程號、成績、績點;
  3. 查詢每個同學的所有課程的平均成績(包括沒有參加考試的同學),顯示如下欄位資訊:學號、姓名、平均成績;
  4. 查詢所有成績對應的學生資訊,沒有對應學生資訊的顯示為空;
  5. 建立學生表和成績的全外連線;
  6. 查詢201課程的最高分學生記錄,使用max函式和一行多列的子查詢兩種方式;
  7. 查詢參加了202課程考試成績中,比所有的201課程分數都低的成績資訊;
  8. 使用exists,完成如下操作:如果103同學參加了201課程的考試,則修改成績為87;
    9.使用in完成如下功能,查詢所有男生的考試成績;
    外來鍵:
  9. 刪除序號為3的學生記錄
  10. 為學生表的學號新增唯一索引;
  11. 為成績表新增外來鍵約束;主鍵表為學生表,關聯欄位為學號;並設定為刪除時RESTRICT,更新時CASCADE;
  12. 刪除【學生表】序號為2的學生記錄;
  13. 更新【學生表】序號為2的學號為3;
  14. 查詢兩個表中的內容;
  15. 修改【成績表】外來鍵約束;並設定為刪除時SET NULL,更新時RESTRICT;
  16. 更新【學生表】序號為3的記錄學號為5;
  17. 刪除【學生表】學號為3的記錄;
  18. 查詢兩個表中的內容;

二、實現

  1. 查詢每個同學的201課程的成績,顯示如下欄位資訊:學號、姓名、課程號、成績、績點;

    select stu.學號,stu.姓名,cj.課程號,cj.成績,cj.績點 from 學生表 stu inner join 成績表 cj on stu.學號 = cj.學號 and cj.課程號 = 201;
    
  2. 查詢每個同學的201課程的成績(包括沒有參加201課程考試的同學),顯示如下欄位資訊:學號、姓名、課程號、成績、績點;

    select stu.學號,stu.姓名,cj.課程號,cj.成績,cj.績點 from 學生表 stu left join 成績表 cj on stu.學號 = cj.學號 and cj.課程號 = 201;
    
  3. 查詢每個同學的所有課程的平均成績(包括沒有參加考試的同學),顯示如下欄位資訊:學號、姓名、平均成績;

    select stu.學號,stu.姓名,avg(cj.成績) 平均成績 from 學生表 stu left join 成績表 cj on stu.學號 = cj.學號 group by 學號;
    
  4. 查詢所有成績對應的學生資訊,沒有對應學生資訊的顯示為空;

    select * from 學生表 stu left join 成績表 cj on stu.學號 = cj.學號;
    
  5. 建立學生表和成績的全外連線;

    select * from 學生表 stu left join 成績表 cj on stu.學號 = cj.學號
    union
    select * from 學生表 stu right join 成績表 cj on stu.學號 = cj.學號;
    
  6. 查詢201課程的最高分學生記錄,使用max函式和一行多列的子查詢兩種方式;

    方式1:
    select max(cj.成績) from 成績表 cj where cj.課程號=201;
    方式2:
    select cj.成績 from 成績表 cj
    where (cj.課程號,cj.成績)=
    (select 課程號,成績 from 成績表 where 課程號=201 order by 成績 desc limit 1)
    limit 1;
    
  7. 查詢參加了202課程考試成績中,比所有的201課程分數都低的成績資訊;

    select * from 成績表
    where 成績<(select min(成績) from 成績表 where 課程號=201) and 課程號 = 202;
    
  8. 使用exists,完成如下操作:如果103同學參加了201課程的考試,則修改成績為87;

    update 成績表 set 成績 = 87
    where exists(select * from (select * from 成績表) a where a.學號=103 and a.課程號=201);
    
  9. 使用in完成如下功能,查詢所有男生的考試成績;

    select 成績 from 成績表
    where 學號 in
    (select 學號 from 學生表 where 性別='男');
    
  10. 刪除序號為3的學生記錄

delete from 學生表 where 序號=3;   
  1. 為學生表的學號新增唯一索引;
alter table 學生表 add unique(學號);
  1. 為成績表新增外來鍵約束;主鍵表為學生表,關聯欄位為學號;並設定為刪除時RESTRICT,更新時CASCADE;
delete from 成績表 where id in(7,8);(不刪除這個外來鍵將建立失敗)
alter table 成績表
add constraint fk_id foreign key(學號) references 學生表(學號)
on delete restrict on update cascade;
  1. 刪除【學生表】序號為2的學生記錄;
delete from 學生表 where 序號=2;
結果:刪除操作被拒絕
  1. 更新【學生表】序號為2的學號為3;
update 學生表 set 學號=3 where 序號=2;
  1. 查詢兩個表中的內容;
select * from 學生表;
select * from 成績表;
結果:從表(成績表)中對應的也更新為3
  1. 修改【成績表】外來鍵約束;並設定為刪除時SET NULL,更新時RESTRICT;
alter table 成績表 drop foreign key fk_id;刪除外來鍵
alter table 成績表 drop key fk_id;刪除系統為外來鍵建立的普通索引
alter table 成績表
add constraint fk_id foreign key(學號) references 學生表(學號)
on delete set null on update restrict;
  1. 更新【學生表】序號為3的記錄學號為5;
update 學生表 set 學號=5 where 學號=3;
結果:更新被拒絕
  1. 刪除【學生表】學號為3的記錄;
delete from 學生表 where 學號=3;   
  1. 查詢兩個表中的內容;
select * from 學生表;
select * from 成績表;
結果:成績表中學號為3的值變為null