日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

山东大学 2020级数据库系统 实验五

發布時間:2025/3/15 windows 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 山东大学 2020级数据库系统 实验五 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

What’s more

山東大學 2020級數據庫系統 實驗一
山東大學 2020級數據庫系統 實驗二
山東大學 2020級數據庫系統 實驗三
山東大學 2020級數據庫系統 實驗四
山東大學 2020級數據庫系統 實驗五
山東大學 2020級數據庫系統 實驗六
山東大學 2020級數據庫系統 實驗七
山東大學 2020級數據庫系統 實驗八、九

寫在前面

做數據庫實驗一定要靜得下心來,才能發現其中的錯誤然后進行改正。同時,如果發現 SQL 語句總是報錯,“一定是你錯了,只是不知道錯在哪里!”

其次,SQL 語句中較為復雜的點博主都進行了注釋,希望大家一定要看懂思路后自己寫一遍,而不是盲目的 Ctrl+C,Ctrl+V,切記切記!!

實驗五

實驗五主要考察的內容如下:
對于聚集函數 sum, max, count 的使用,同時有無 group by 的意識;

對于分部分查詢的熟練程度;(可能會有其他方法,但這部分我分塊查詢用的比較多~~

對于 union all 的了解及區分 union all 和 union 的區別;

  • 5-1 在學生表pub.student中統計名字(姓名的第一位是姓氏,其余為名字,不考慮復姓)的使用的頻率,將統計結果放入test5_01中,表結構如下。
    First_name varchar(4) frequency numeric(4)
    國強 1034
    紅 1232
    衛東 2323
    ………………

    思路:
  • 使用 substr() 函數取出名字中的姓;
  • 然后對所有姓進行 count 計數即可
create table test5_01 asselect distinct substr(name, 2, length(name)) first_name, count(*) frequencyfrom pub.studentgroup by substr(name, 2, length(name))
  • 5-2 在學生表pub.student中統計名字(姓名的第一位是姓氏,不作統計,名字指姓名的第二個之后的漢字)的每個字使用的頻率,將統計結果放入test5_02中(特別提示:需要區別union和union all的不同),表結構如下。
    letter varchar(2) frequency numeric(4)
    鋒 1034
    紅 1232
    鵬 2323
    ………………

    避坑指南:

  • 需要先選出姓名中的第二個字和第三個字,然后再對他們進行統一的計數;
  • 思路:
    1. 選出名字中的第二個字,記為集合 A,然后使用 union all 來連接名字中第三個字的集合,記為B;(union 和 union all 的區別在于一個去重,一個不去重)
    2. 然后對 A ∪\cup B 進行統一的計數即可;

create table test5_02(letter varchar(2),frequency numeric(4)) insert into test5_02 select letter, count(*) frequency from ((select substr(name, 2, 1) letterfrom pub.studentwhere substr(name, 2, 1) is not null)union all(select substr(name, 3, 1) letterfrom pub.studentwhere substr(name, 3, 1) is not null)) group by letter
  • 5-3 創建"學院班級學分達標情況統計表1"test5_03,依據pub.student, pub.course,pub.student_course統計形成表中各項數據,成績>=60為及格計入學分,總學分>=10算作達標,院系為空值的數據不統計在下表中,表結構:院系名稱dname、班級class、學分達標人數p_count1、學分未達標人數p_count2、總人數p_count。
    Dname varchar(30) class varchar(10) P_count1 Int P_count2 int P_count int
    計算機學院 2006
    計算機學院 2007
    軟件學院 2006
    ………………

    注意:此題較難,如果你現在靜不下來,那就下下道題吧;如果能夠靜下來,Let’s go
    避坑指南:

  • “成績 >= 60” 是指該學生該門課的成績的最大值 >= 60;(可能有考了多次的學生)
  • 有的學生在 pub.student 中,但是他沒有選課,因此又不在 pub.student_course 中。這部分學生應該算作學分未達標 p_count2。因此,這部分這么難算,為何不用 p_count - p_count1 呢?(我也給出計算 p_count2 的代碼啦,有興趣可以看看~~)
  • 有的學院班級的學生全部都學分不達標;(其實只有一個‘生命科學學院 2008’,幫忙就幫到這兒啦,具體人數還是自己算一算哈~~)當時卡了我好久/(ㄒoㄒ)/~~
  • 思路:(分塊查詢)

  • 先從 pub.student 中選出 dname, class, p_count,結果記為 t1;
  • 再從 t2 表中找到 p_count1:需要先找到每個學生每門課的最高分,在通過最高分判定是否得到相應的學分,再用 sum(credit) 來得到學分的和,最后進行判定;
  • p_count2 使用 p_count - p_count1 即可;
create table test5_03(dname varchar(30),class varchar(10),p_count1 int,p_count2 int,p_count int) -----------一張表一張表地看思路更清晰哦(一共就 t1,t2 兩張表)-------------- insert into test5_03 select t1.dname, t1.class, t2.p_count1, (t1.p_count - t2.p_count1) p_count2, t1.p_count from (select distinct dname, class, count(*) p_countfrom pub.studentwhere dname is not nullgroup by dname, class) t1, --t1 表:找到 dname, class, p_count(select distinct dname, class, count(*) p_count1from (select sid, dname, class, sum(credit) sum_credit --找到總學分from (select sid, cid, dname, class, max(score) max_score --找到成績的最大值from pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60 --最大成績 >= 60 才計入學分and dname is not nullgroup by sid, dname, class)where sum_credit >= 10 --總學分 > 10 才選出來group by dname, class) t2, --t2 表:找到 p_count1(找 dname 和 class 是為了在后面進行連接)where t1.dname = t2.dname and t1.class = t2.class

現在給出計算 p_count2 的代碼,有興趣可以看看哈~~

select distinct dname, class, count(*) p_count2 from ((select sid, dname, class, sum(credit) sum_credit --選了課但是沒有達標的學生from (select sid, cid, dname, class, max(score) max_scorefrom pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60and dname is not nullgroup by sid, dname, class) union(select distinct sid, dname, class, 0 as sum_credit --在 pub.student 中但是不在 pub.student_course 中的學生,這部分學生也算作不達標哦~~from pub.studentwhere sid not in(select sidfrom pub.student_course))) where sum_credit < 10 group by dname, class
  • 5-4 創建"學院班級學分達標情況統計表2"test5_04,依據pub.student, pub.course,pub.student_course統計形成表中各項數據,成績>=60為及格計入學分,2008級及之前的班級總學分>=8算作達標,2008級之后的班級學分>=10算作達標,院系為空值的數據不統計在下表中,表結構:院系名稱dname、班級class、學分達標人數p_count1、學分未達標人數p_count2、總人數p_count。
    Dname varchar(30) class varchar(10) P_count1 int P_count2 int P_count int
    計算機學院 2006
    計算機學院 2007
    軟件學院 2006
    ………………

    思路:
  • 如果你看懂了 5-3 的思路,那么相信這道題對你來說會比較簡單。只需要改變一下條件,增加一個判定即可;
create table test5_04(dname varchar(30),class varchar(10),p_count1 int,p_count2 int,p_count int) -----------一張表一張表地看思路更清晰哦(一共就 t1,t2 兩張表)-------------- insert into test5_04 select t1.dname, t1.class, t2.p_count1, (t1.p_count - t2.p_count1) p_count2, t1.p_count from (select distinct dname, class, count(*) p_countfrom pub.studentwhere dname is not nullgroup by dname, class) t1,(select distinct dname, class, count(*) p_count1from (select sid, dname, class, sum(credit) sum_creditfrom (select sid, cid, dname, class, max(score) max_scorefrom pub.student_course natural join pub.studentgroup by sid, cid, dname, class) natural join pub.coursewhere max_score >= 60and dname is not nullgroup by sid, dname, class)where sum_credit >= --Look at here! 增加的條件在這里 —— 就是根據 class 來決定 sum_credit 的判定條件哦casewhen class <= 2008 then 8when class > 2008 then 10endgroup by dname, class) t2where t1.dname = t2.dname and t1.class = t2.class

手動算 p_count2 也是在相同的地方加上 case 即可。

  • 5-5 注意事項:
    如果一個學生一門課程有多次成績,僅僅計算最高成績,也就是只用他的最好成績參加如下統計。
    5. 查詢各院系(不包括院系名稱為空的)的數據結構平均成績avg_ds_score、操作系統平均成績avg_os_score,平均成績四舍五入到個位,創建表test5_05,表結構及格式如下:
    Dname Avg_ds_score Avg_os_score
    馬克思主義學院 72 70
    軟件學院 77 74
    藝術學院 77 76
    醫學院 74 73

    思路:
  • 主要還是運用了分塊查詢的思想;
  • 先從 t1 表中找到唯一的 dname 屬性值;
  • 然后從 t2 表中找到“數據結構”課程成績的平均值;(注意其中包含了一個求最大值的過程)
  • 同樣,接著從 t2 表中找到“操作系統”課程成績的平均值;(也有一個求最大值的過程)
  • 最后使用 dname 來進行連接即可;(或者直接 natural join 也行)
create table test5_05(dname varchar(20),avg_ds_score int,avg_os_score int); insert into test5_05 select distinct t1.dname, t2.avg_ds_score, t3.avg_os_score from(select distinct dnamefrom pub.student) t1,(select distinct dname, round(avg_ds_score, 0) avg_ds_scorefrom (select distinct dname, avg(max_ds_score) avg_ds_scorefrom (select distinct sid, dname, max(score) max_ds_scorefrom pub.student natural join pub.student_coursewhere cid = (select cid from pub.course where name = '數據結構')group by sid, dname)group by dname)) t2,(select distinct dname, round(avg_os_score, 0) avg_os_scorefrom (select distinct dname, avg(max_os_score) avg_os_scorefrom (select distinct sid, dname, max(score) max_os_scorefrom pub.student natural join pub.student_coursewhere cid = (select cid from pub.course where name = '操作系統')group by sid, dname)group by dname)) t3 where t1.dname = t2.dname and t2.dname = t3.dname
  • 5-6 查詢"計算機科學與技術學院"的同時選修了數據結構、操作系統兩門課的學生的學號sid、姓名name、院系名稱dname、數據結構成績ds_score、操作系統成績os_score,創建表test5_06。
    思路:
  • 分塊查詢:先找到同時選了這兩門課的學生的 sid, name,在分別找這兩門課的成績;
  • 使用存在性檢測 not exists … except(minus) … 結構可以找到同時選修了這兩門課的學生的 sid, name;
  • 需要注意的是:這兩門課的成績都需要用對應成績的最大值哦~~
create table test5_06 asselect t1.sid, t1.name, '計算機科學與技術學院' as dname, t2.ds_score, t3.os_scorefrom (select sid, namefrom pub.student Swhere dname = '計算機科學與技術學院'and not exists( (select cidfrom pub.coursewhere name = '數據結構' or name = '操作系統')minus(select cidfrom pub.student_course Twhere S.sid = T.sid))) t1,(select sid, max(score) ds_scorefrom pub.student_coursewhere cid = (select cid from pub.course where name = '數據結構')group by sid) t2,(select sid, max(score) os_scorefrom pub.student_coursewhere cid = (select cid from pub.course where name = '操作系統')group by sid) t3where t1.sid = t2.sidand t2.sid = t3.sid
  • 5-7 查詢計算機科學與技術學院的選修了數據結構或者操作系統的學生的學號sid、姓名name、院系名稱dname、數據結構成績ds_score、操作系統成績os_score,創建表test5_07。
    思路:
  • 先去找到計算機科學與技術學院選修了“數據結構”或者“操作系統”的學生的 sid, name;
  • 由于二者只修其一的學生我們同樣需要將它保留下來,因此可以使用 natural left outer join來連接成績;
  • 這兩門課的成績同樣注意使用最大值即可;
create table test5_07 asselect sid, name, dname, ds_score, os_scorefrom (select distinct sid, name, dnamefrom pub.student natural join pub.student_coursewhere dname = '計算機科學與技術學院'and cid in (select cid from pub.course where name = '數據結構' or name = '操作系統')) natural left outer join (select distinct sid, max(score) ds_scorefrom pub.student_course natural join pub.coursewhere name = '數據結構'group by sid)natural left outer join(select distinct sid, max(score) os_scorefrom pub.student_course natural join pub.coursewhere name = '操作系統'group by sid)
  • 5-8 查詢計算機科學與技術學院所有學生的學號sid、姓名name、院系名稱dname、數據結構成績ds_score、操作系統成績os_score,創建表test5_08。
    思路:
  • 直接找到計算機科學與技術學院所有學生的 sid, name;
  • 接著找到每門課成績的最大值;
  • 最后使用 natural left outer join 即可;
create table test5_08 asselect sid, name, dname, ds_score, os_scorefrom (select distinct sid, name, dnamefrom pub.studentwhere dname = '計算機科學與技術學院') natural left outer join (select distinct sid, max(score) ds_scorefrom pub.student_course natural join pub.coursewhere name = '數據結構'group by sid)natural left outer join(select distinct sid, max(score) os_scorefrom pub.student_course natural join pub.coursewhere name = '操作系統'group by sid)

再次強調:一定是看懂思路之后自己實踐哈~~
有問題還請斧正!

總結

以上是生活随笔為你收集整理的山东大学 2020级数据库系统 实验五的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。