山东大学 2020级数据库系统 实验二
What’s more
山東大學 2020級數據庫系統 實驗一
山東大學 2020級數據庫系統 實驗二
山東大學 2020級數據庫系統 實驗三
山東大學 2020級數據庫系統 實驗四
山東大學 2020級數據庫系統 實驗五
山東大學 2020級數據庫系統 實驗六
山東大學 2020級數據庫系統 實驗七
山東大學 2020級數據庫系統 實驗八、九
寫在前面
做數據庫實驗一定要靜得下心來,才能發現其中的錯誤然后進行改正。同時,如果發現 SQL 語句總是報錯,“一定是你錯了,只是不知道錯在哪里”
其次,SQL 語句中較為復雜的點博主都進行了注釋,希望大家一定要看懂思路后自己寫一遍,而不是盲目的 Ctrl+C,Ctrl+V,切記切記!!
實驗二
注意:實驗二使用的表是:pub.student_course, pub.student, pub.course 哦,別搞錯了!!
檢索查詢部分應該算是數據庫中較為困難的一部分了,每道題我會先寫出思路,同時在 SQL 語句中進行注釋,希望能夠看懂。
- 2-1 找出沒有選修任何課程的學生的學號、姓名(即沒有選課記錄的學生)
思路: - 找出有選課記錄的同學的學號,不妨記為關系 A;
- 使用 not in 在 pub.student 中篩選不在 A 中有記錄的學生的學號及姓名;
-
2-2 找出至少選修了學號為“200900130417”的學生所選修的一門課的學生的學號、姓名(不包含這名同學)。
思路 1: - 選出該同學所選修了的課程號 cid,作為集合 A;
- 使用 = some 來對 pub.student_course 中每個同學的課程號 cid 進行篩選;
- 最后在 pub.student 中選出對應的學號 sid 及姓名 name
- 選出該同學所選修了的課程號 cid,作為集合 A;
- 使用 in 根據 A 篩選出課程號在集合 A 中的同學對應的學號及姓名;
- 集合運算 minus(except) 減去該同學的學號及姓名
思路 2:
-
2-3 找出至少選修了一門其先行課程號為“300002”號課程的學生的學號、姓名
思路: - 根據先行課程號 fcid 在 pub.course 中選出對應的選修課程號 cid,記為集合 A;
- 在 pub.student_course 中根據集合 A 篩選出所選課程在 A 中的學生的 sid,記為集合 B;
- 在 pub.student 中根據集合 B 篩選出對應學生的 sid 和 name;
第 2 步以及第 3 步可以使用 natural join 進行連接。
-
2-4 找出選修了“操作系統”并且也選修了“數據結構”,但是沒有選修“程序設計語言”的學生的學號、 姓名
思路: - 找出選修了“操作系統”的學生的 sid,記為集合 A;
- 找出選修了“數據結構”的學生的 sid,記為集合 B;
- 找出沒有選修“程序設計語言”的學生的 sid,記為集合 C;
- (A intersect B) except C 即可;
(注意 Oracle 中將 except 換為 minus 就行)
-
2-5 查詢 20 歲的所有有選課的學生的學號、姓名、平均成績(avg_score,此為列名,下同)(平均成績四舍 五入到個位)、總成績(sum_score)
思路: - 使用 natural join 將 pub.student 和 pub.student_course 連接起來;
- 計算對應的信息即可;
注意:函數 round(number, precision) 可以將 number 按照 precision 精確到對應位。round(avg(number), 0) 即代表將 score 的平均值保留到整數位。
-
2-6 查詢所有課的最高成績、最高成績人數,test2_06 有四個列:課程號 cid、課程名稱 name、最高成績 max_score、最高成績人數 max_score_count(一個學生同一門課成績都是第一,只計一次,需要考慮刷 成績情況,一個同學選了一個課程多次,兩次都是最高分。如果結果錯一行,可能就是沒有考慮這種情 況,這里是為了考核“去重復計數”知識點的)。如果沒有學生選課,則最高成績為空值,最高成績人 數為零
此題應該算是實驗二中最難的一道了。希望我能將思路說清楚
主要用到的表如下: - t1:得出 cid,name
- t2:得出max_score
- t5:得出max_score_count
思路:
1. t1, t2 表的求解過程不用多說,簡單的分組查詢(查詢時一定要加上 cid ,因為后面要將它們連接起來);
2. 由于需要數最高分的人數,因此首先要在查詢 max_score_count 部分的 from 子句中計算出 max_score (t4 表);
3. 然后針對 score 對學生進行篩選,讓 t3.cid = t4.cid 以及 t3.score = t4.max_score,得出每門課的最高分的學生的信息;
4. 再進行分組后 count 得到 max_score_count;
5. 最后將這些表的信息連起來 t1.cid = t2.cid and t2.cid = t5.cid;
-
2-7 查詢所有不姓張、不姓李、也不姓王的學生的學號 sid、姓名 name
思路 1: - 直接使用函數 substr(string, p1, p2),該函數可以針對取得字符串相對應部分的字符。如 substr(name, 0, 1) 就可以取得學生姓名 name 的第一個字符,即為姓。
- 然后接著判斷取得的字符串是否是“張”、“李”、“王”即可。
- 使用 not like 子句對字符串進行處理即可;
思路 2:
- 2-8 查詢學生表中每一個姓氏及其人數(不考慮復姓),test2_08 有兩個列:second_name、p_count
思路: - 使用 substr 函數來取得學生的姓,然后進行 count 即可;
- 2-9 查詢選修了 300003 號課程的學生的 sid、name、score
思路: - 使用 natural join 將 pub.student 和 pub.student_course 進行連接;
- 從中尋找對應的 sid, name 以及 score;
-
2-10 找出同一個同學同一門課程有兩次或以上不及格的所有學生的學號、姓名(即一門課程需要補考兩次 或以上的學生的學號、姓名)
思路 1: - 先選出 score < 60 的學生,并將此時的 pub.student_course 記為 S;
- 然后將子查詢中的 pub.student_course 記為 T,在 S.cid = T.cid, T.score < 60 的條件下,查找是否還存在記錄;
- 若存在,則滿足條件;不滿足則不輸出;
- 選出分數 < 60 的學生的 sid 以及 cid,并按照這兩個標準對 pub.student_course進行分組;
- 在分組的基礎上使用 count 來數出每一組的人數。若人數 > 2,則滿足條件,記錄其 sid;反之則不記錄;
思路 2:
再次強調:一定是看懂思路之后自己實踐哈~~
有問題還請斧正!
總結
以上是生活随笔為你收集整理的山东大学 2020级数据库系统 实验二的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java对外查询接口注意的地方_Java
- 下一篇: R语言基础入门(4)之数据类型与相应运算