山东大学 2020级数据库系统 实验四
What’s more
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)一
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)二
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)三
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)四
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)五
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)六
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)七
山東大學(xué) 2020級(jí)數(shù)據(jù)庫(kù)系統(tǒng) 實(shí)驗(yàn)八、九
寫在前面
做數(shù)據(jù)庫(kù)實(shí)驗(yàn)一定要靜得下心來(lái),才能發(fā)現(xiàn)其中的錯(cuò)誤然后進(jìn)行改正。同時(shí),如果發(fā)現(xiàn) SQL 語(yǔ)句總是報(bào)錯(cuò),“一定是你錯(cuò)了,只是不知道錯(cuò)在哪里!”
其次,SQL 語(yǔ)句中較為復(fù)雜的點(diǎn)博主都進(jìn)行了注釋,希望大家一定要看懂思路后自己寫一遍,而不是盲目的 Ctrl+C,Ctrl+V,切記切記!!
實(shí)驗(yàn)四
實(shí)驗(yàn)四主要考察的內(nèi)容如下:
對(duì)于 alter 語(yǔ)句的掌握程度以及是否能夠使用它來(lái)對(duì)表中的屬性進(jìn)行操作;
對(duì)于 update … set … where 子句的使用;
對(duì)字符串的處理以及刪除字符串中相應(yīng)的字符;
- 4-1 將 pub 用戶下表 student_41 及數(shù)據(jù)復(fù)制到主用戶的表 test4_01 中,使用 alter table 語(yǔ)句為表增加列: “總成績(jī):sum_score”。
使用 update 語(yǔ)句,利用 pub.student_course,統(tǒng)計(jì) “總成績(jī)”;
思路: - 先指用 alter table test4_01 add sum_score int 來(lái)添加對(duì)應(yīng)的屬性列。需要注意的是 add 子句后面的屬性列還有跟上該列的類型說(shuō)明;
- 使用 update … set … 結(jié)構(gòu)計(jì)算每個(gè)學(xué)生的總成績(jī)?nèi)缓筇钊?sum_score 列中即可;
-
4-2 將 pub 用戶下表 student_41 及數(shù)據(jù)復(fù)制到主用戶的表 test4_02 中,使用 alter table 語(yǔ)句為表增加列 “平均成績(jī):avg_score” (小數(shù)點(diǎn)后保留 1 位)。
利用 pub.student_course,統(tǒng)計(jì)“平均成績(jī)”,四舍五入到小數(shù)點(diǎn)后 1 位
思路: - 思路其實(shí)和 4-1 相似,添加對(duì)應(yīng)列,然后分別進(jìn)行平均成績(jī)的計(jì)算即可;
- 保留小數(shù)點(diǎn)后 1 位使用 round() 函數(shù)即可;
需要注意的是:在對(duì) avg_score 屬性列進(jìn)行定義的時(shí)候,由于保留一位小數(shù),因此需要使用 numeric(3, 1) 來(lái)設(shè)置哦~~
- 4-3 將 pub 用戶下表 student_41 及數(shù)據(jù)復(fù)制到主用戶的表 test4_03 中,使用 alter table 語(yǔ)句為表增加列: “總學(xué)分:sum_credit”。
使用 update 語(yǔ)句,利用 pub.student_course、pub.course,統(tǒng)計(jì) “總學(xué)分”;
這時(shí)需要注意:成績(jī)及格才能夠計(jì)算所得學(xué)分,一門課多個(gè)成績(jī)都及格只計(jì)一次學(xué)分。
思路: - 使用 alter … add … 來(lái)添加對(duì)應(yīng)的屬性列,同時(shí)注意列屬性的定義為 int 即可;
- 注意題目中的提示“一門課多個(gè)成績(jī)都及格只計(jì)一次學(xué)分”,因此我們不能簡(jiǎn)單地使用 score > 60 然后 sum(credit) ;正確的方法應(yīng)該是得到每個(gè)學(xué)生每門課的最高成績(jī),用這個(gè)最高成績(jī)來(lái)判斷是否 > 60,若大于 60 ,則計(jì)一次學(xué)分;由于每個(gè)學(xué)生的最高分是唯一的,因此我們?cè)?sum(credit) 時(shí)相當(dāng)于只計(jì)算了一次,而不是像前者一樣計(jì)算多次。
- 4-4 將 pub 用戶下表 student_41 及數(shù)據(jù)復(fù)制到主用戶的表 test4_04 中。 根據(jù)列院系名稱 dname 到 pub.department 找到對(duì)應(yīng)院系編號(hào) did,將對(duì)應(yīng)的院系編號(hào)回填到院系名稱列 dname 中,如果表中沒有對(duì)應(yīng)的院系名稱,則列 dname 中內(nèi)容不變?nèi)匀皇窃瓉?lái)的內(nèi)容。
思路: - 首先使用 create table … as select * … 來(lái)將 pub.student_41 中的所有數(shù)據(jù) copy 到 test4_04 中;
- 然后使用 dname 去判斷這個(gè) dname 是否在 pub.department 中;
- 若是,則將 dname 更新為相應(yīng)的 did;反之則不更新;
- 4-5 將 pub 用戶下表 student_41 及數(shù)據(jù)復(fù)制到主用戶的表 test4_05 中,使用 alter table 語(yǔ)句為表增加 4 個(gè)列:“總成績(jī):sum_score”、 “平均成績(jī):avg_score”、“總學(xué)分:sum_credit”、“院系編號(hào):did varchar(2) ”。
(1) 利用 pub.student_course、pub.course,統(tǒng)計(jì) “總成績(jī)”;
(2) 利用 pub.student_course、pub.course,統(tǒng)計(jì)“平均成績(jī)”,四舍五入到小數(shù)點(diǎn)后 1 位;
(3) 利用 pub.student_course、pub.course,統(tǒng)計(jì) “總學(xué)分”;
(4) 根據(jù)院系名稱到 pub.department 和 pub.department_41 中,找到對(duì)應(yīng)編號(hào),填寫到院系編號(hào)中, 如果都沒有對(duì)應(yīng)的院系,則填寫為 00。
說(shuō)明:執(zhí)行 update 后,在查詢表中數(shù)據(jù),可能出現(xiàn)順序變化,這是正常,因?yàn)閿?shù)據(jù)在表中是無(wú)序。需要 順序的時(shí)候可以通過(guò) orderby 實(shí)現(xiàn)。
思路: - 首先使用 create 語(yǔ)句進(jìn)行表和數(shù)據(jù)的復(fù)制;
- 然后使用 alter table 語(yǔ)句在復(fù)制得到的表中添加對(duì)應(yīng)列;注意 alter 似乎不能一起添加,因此需要一列一列地進(jìn)行屬性列地添加;
- 最后使用 update … set … 子句來(lái)對(duì)表中的屬性列進(jìn)行更新即可(set 可以同時(shí)更新多列哦~~)
需要注意的是:對(duì)于院系編號(hào)地更新時(shí),現(xiàn)在是從兩個(gè)表中尋找對(duì)應(yīng)的院系編號(hào)而不是一個(gè)表了(當(dāng)時(shí)卡了好久/(ㄒoㄒ)/~~),這兩個(gè)表可以通過(guò) union 來(lái)連接。(由于是前面問(wèn)題的綜合,因此代碼較長(zhǎng))
create table test4_05 as select * from pub.student_41 alter test4_05add sum_score int -----------------分開哦----------------------- alter test4_05add avg_score numeric(3, 1) -----------------分開哦----------------------- alter test4_05add sum_credit int -----------------分開哦----------------------- alter test4_05add did varchar(2) update test4_05 t0 set sum_score = (select sum(score)from pub.student_course t1where t0.sid = t1.sidgroup by sid), avg_score =(select round(avg(score), 1)from pub.student_course t2where t0.sid = t2.sidgroup by sid), sum_credit = (select sum(credit)from pub.course natural join (select sid, cid, max(score) max_scorefrom pub.student_coursegroup by sid, cid) t1where t0.sid = sidand t1.max_score >= 60group by sid), did = casewhen dname in( (select dnamefrom pub.department)union(select dnamefrom pub.department_41) )then(select didfrom ( (select dname, didfrom pub.department)union(select dname, didfrom pub.department_41) )where dname = t0.dname) else '00' end- 4-6 將 pub 用戶下的 Student_42 及數(shù)據(jù)復(fù)制到主用戶的表 test4_06 中,對(duì)表中的數(shù)據(jù)進(jìn)行整理,修復(fù)那些不規(guī)范的數(shù)據(jù): 剔除姓名列中的所有空格;
思路: -
使用 create 來(lái)將表和數(shù)據(jù)進(jìn)行復(fù)制;
-
為了刪除空格,我們可以使用函數(shù) replace(string, target_str, replace_str) 來(lái)進(jìn)行;
第一個(gè)參數(shù) string 表示需要修改的字符串;第二個(gè)參數(shù) target_str 表示在該字符串中需要修改的字符(為了查找到該字符);第三個(gè)參數(shù) replace_str 表示需要將 target_str 替換為什么字符;
在本題中,我們可以這樣使用 replace 函數(shù):replace(name, ’ ', ‘’),找到空格并將它刪去;(translate()函數(shù)也有類似的功能!)
- 4-7 將 pub 用戶下的 Student_42 及數(shù)據(jù)復(fù)制到主用戶的表 test4_07 中,對(duì)表中的數(shù)據(jù)進(jìn)行整理,修復(fù)那些不規(guī)范的數(shù)據(jù): 對(duì)性別列進(jìn)行規(guī)范(需要先確定哪些性別數(shù)據(jù)不規(guī)范,也就是那些和大多數(shù)不一樣的就是不規(guī)范的);
思路: - 使用 create 子句來(lái)對(duì)表和表中的數(shù)據(jù)進(jìn)行復(fù)制;
- 為了看到哪些才是不規(guī)范的數(shù)據(jù),我們可以首先使用:
select distinct sex, count(sex) from test4_07 group by sex
來(lái)查看所謂的“不規(guī)范數(shù)據(jù)”。發(fā)現(xiàn):不規(guī)范的數(shù)據(jù)是加上了“性”字的 sex 值,同時(shí)有些 sex 值的前后可能還有空格等; - 具體的刪除方法我們還是可以使用 replace() 函數(shù);
- 4-8 將 pub 用戶下的 Student_42 及數(shù)據(jù)復(fù)制到主用戶的表 test4_08 中,對(duì)表中的數(shù)據(jù)進(jìn)行整理,修復(fù)那些不規(guī)范的數(shù)據(jù): 對(duì)班級(jí)列進(jìn)行規(guī)范(需要先確定哪些班級(jí)不規(guī)范)。
思路: - 首先使用 create 來(lái)對(duì)表以及表中的數(shù)據(jù)進(jìn)行復(fù)制;
- 然后使用
select distinct class, count(class) from test4_08 group by class
來(lái)看看哪些班級(jí)數(shù)據(jù)是不規(guī)范的數(shù)據(jù)。發(fā)現(xiàn),不規(guī)范的班級(jí)數(shù)據(jù)后面又“級(jí)”字,我們只需要使用 replace() 函數(shù)來(lái)將它去掉即可;
- 4-9 將 pub 用戶下的 Student_42 及數(shù)據(jù)復(fù)制到主用戶的表 test4_09 中,對(duì)表中的數(shù)據(jù)進(jìn)行整理,修復(fù)那些不規(guī)范的數(shù)據(jù): 年齡為空值的根據(jù)出生日期設(shè)置學(xué)生年齡(截止到 2012 年的年齡,即年齡=2012-出生年份),年齡不 為空值的不要改變。
思路: - 首先使用 create 來(lái)對(duì)表以及表中的數(shù)據(jù)進(jìn)行復(fù)制;
- 然后使用 update 和 where 判定語(yǔ)句來(lái)對(duì) age 列進(jìn)行更新即可;
- 期間還是用到了實(shí)驗(yàn)三中提到的 extract() 函數(shù)哦~~
- 4-10 將 pub 用戶下的 Student_42 及數(shù)據(jù)復(fù)制到主用戶的表 test4_10 中,對(duì)表中的數(shù)據(jù)進(jìn)行整理,修復(fù)那些不規(guī)范的數(shù)據(jù):
(1) 剔除姓名列中的所有空格;
(2) 剔除院系名稱列中的所有空格;
(3) 對(duì)性別列進(jìn)行規(guī)范(需要先確定哪些性別數(shù)據(jù)不規(guī)范,也就是那些和大多數(shù)不一樣的就是不規(guī)范的);
(4) 對(duì)班級(jí)列進(jìn)行規(guī)范(需要先確定哪些班級(jí)不規(guī)范)。
(5) 年齡為空值的根據(jù)出生日期設(shè)置學(xué)生年齡(截止到 2012 年的年齡,即年齡=2012-出生年份), 年齡不為空值的不要改變。
思路: - 就是對(duì)前面所有的問(wèn)題的綜合,由于 set 中可以同時(shí)設(shè)置多個(gè)列,因此將它們連接起來(lái)即可;
再次強(qiáng)調(diào):一定是看懂思路之后自己實(shí)踐哈~~
有問(wèn)題還請(qǐng)斧正!
總結(jié)
以上是生活随笔為你收集整理的山东大学 2020级数据库系统 实验四的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数学建模学习笔记(四)——拟合算法
- 下一篇: python写算法求最短路径,Pytho