学生表 成绩表 课程表 教师表
學生表:
Student(s_id,s_name,s_birth,s_sex) –學生編號,學生姓名, 出生年月,學生性別
課程表:
Course(c_id,c_name,t_id) – –課程編號, 課程名稱, 教師編號
教師表:
Teacher(t_id,t_name) –教師編號,教師姓名
成績表:
Score(s_id,c_id,s_s_score) –學生編號,課程編號,分數
根據以上信息按照下面要求寫出對應的SQL語句。
ps:這些題考察SQL的編寫能力,對于這類型的題目,需要你先把4張表之間的關聯關系搞清楚了,最好的辦法是自己在草稿紙上畫關聯圖,然后再編寫對應的SQL語句就比較容易了。
下圖是我在草稿紙上畫的這4張表的關系圖,不好理解,你可以列舉一些數據案例來輔助理解:
案例數據建立參考如下
表名和字段
–1.學生表
Student(s_id,s_name,s_birth,s_sex) –學生編號,學生姓名, 出生年月,學生性別
–2.課程表
Course(c_id,c_name,t_id) – –課程編號, 課程名稱, 教師編號
–3.教師表
Teacher(t_id,t_name) –教師編號,教師姓名
–4.成績表
Score(s_id,c_id,s_score) –學生編號,課程編號,分數
建立數據庫、建表和插入數據
題目:思路、關鍵函數、解題語句、結果
知識點
語句表
建表和插入數據
新建數據庫
數據庫屬性 utf8 -- UTF-8 Unicode
排序規則 utf8_unicode_ci
建表(創建查詢,復制下方語句到查詢中,運行即可)
-- 學生表 -- Student(s_id,s_name,s_birth,s_sex) -- 學生編號,學生姓名, 出生年月,學生性別 CREATE TABLE `Student`( `s_id` VARCHAR(20), `s_name` VARCHAR(20) NOT NULL DEFAULT '', `s_birth` VARCHAR(20) NOT NULL DEFAULT '', `s_sex` VARCHAR(10) NOT NULL DEFAULT '', PRIMARY KEY(`s_id`) ); -- 課程表 -- Course(c_id,c_name,t_id) -- 課程編號, 課程名稱, 教師編號 CREATE TABLE `Course`( `c_id` VARCHAR(20), `c_name` VARCHAR(20) NOT NULL DEFAULT '', `t_id` VARCHAR(20) NOT NULL, PRIMARY KEY(`c_id`) ); -- 教師表 -- Teacher(t_id,t_name) -- 教師編號,教師姓名 CREATE TABLE `Teacher`( `t_id` VARCHAR(20), `t_name` VARCHAR(20) NOT NULL DEFAULT '', PRIMARY KEY(`t_id`) ); -- 成績表 -- Score(s_id,c_id,s_s_score) -- 學生編號,課程編號,分數 CREATE TABLE `Score`( `s_id` VARCHAR(20), `c_id` VARCHAR(20), `s_score` INT(3), PRIMARY KEY(`s_id`,`c_id`) )插入數據(創建查詢,復制下方語句到查詢中,運行即可)
-- 學生表數據 insert into Student values('01' , '趙雷' , '1990-01-01' , '男'); insert into Student values('02' , '錢電' , '1990-12-21' , '男'); insert into Student values('03' , '孫風' , '1990-05-20' , '男'); insert into Student values('04' , '李云' , '1990-08-06' , '男'); insert into Student values('05' , '周梅' , '1991-12-01' , '女'); insert into Student values('06' , '吳蘭' , '1992-03-01' , '女'); insert into Student values('07' , '鄭竹' , '1989-07-01' , '女'); insert into Student values('08' , '王菊' , '1990-01-20' , '女'); -- 教師表數據 insert into Teacher values('t01' , '張三'); insert into Teacher values('t02' , '李四'); insert into Teacher values('t03' , '王五'); -- 課程表數據 insert into Course values('01' , '語文' , '02'); insert into Course values('02' , '數學' , '01'); insert into Course values('03' , '英語' , '03');-- 成績表數據 insert into Score values('01' , '01' , 80); insert into Score values('01' , '02' , 90); insert into Score values('01' , '03' , 99); insert into Score values('02' , '01' , 70); insert into Score values('02' , '02' , 60); insert into Score values('02' , '03' , 80); insert into Score values('03' , '01' , 80); insert into Score values('03' , '02' , 80); insert into Score values('03' , '03' , 80); insert into Score values('04' , '01' , 50); insert into Score values('04' , '02' , 30); insert into Score values('04' , '03' , 20); insert into Score values('05' , '01' , 76); insert into Score values('05' , '02' , 87); insert into Score values('06' , '01' , 31); insert into Score values('06' , '03' , 34); insert into Score values('07' , '02' , 89); insert into Score values('07' , '03' , 98);?
刷新‘表‘就能看見建立的表了
題目
-- 1.查詢課程編號為‘01’的課程比‘02’的課程成績高的所有學生的學號、姓名和各自‘01’‘02’課程成績
思路:通過學生編號將成績表的課程‘01’成績和課程‘02’成績構建一張新表包含:學生編號、課程‘01’成績、課程‘02成績’
關鍵函數:SELECT...FROM...INNER JOIN...ON...WHERE...
解題語句:
SELECT a.s_id ,c.s_name,a.s_score '01',b.s_score '02'FROM (SELECT s_id,c_id,s_score FROM score WHERE c_id='01')AS a INNER JOIN (SELECT s_id,c_id,s_score FROM score WHERE c_id='02')AS b ON a.s_id=b.s_id INNER JOIN student AS c ON a.s_id=c.s_id WHERE a.s_score>b.s_score;結果:
-- 2、查詢平均成績大于60分的學生的學號和平均成績
思路:以學生學號進行分組,算平均成績,篩選輸出平均成績大于60分的學生學號和平均成績
關鍵函數:GROUP BY、 AVG()
解題語句:
SELECT s_id,AVG(s_score) FROM score GROUP BY s_id HAVING AVG(s_score)>60結果:
-- 3、查詢所有學生的學號、姓名、選課數、總成績
思路:學生表通過學生學號左關聯成績表,以學生學號進行分組,count函數計算選課數,sum函數計算總成績,ifnull函數將由于左關聯產生的成績表中沒有的同學數據null變成0
關鍵函數:GROUP BY、COUNT()、SUM()、IFNULL( , )、LEFT JOIN
解題語句:
SELECT a.s_id,a.s_name,COUNT(b.c_id),SUM(IFNULL(b.s_score,0)) FROM student AS a LEFT JOIN score AS b ON a.s_id=b.s_id GROUP BY s_id結果:
-- 4、查詢姓“張”的老師的個數
思路:用like篩選老師姓名,避免姓名重復通過計算老師id來計算個數
關鍵函數:LIKE、COUNT
解題語句:
SELECT COUNT(t_id) FROM teacher WHERE t_name LIKE '張%'結果:
-- 5、查詢沒學過“張三”老師課的學生的學號、姓名
思路1:多層嵌套、子查詢
通過教師表查詢得姓名為‘張三’的教師編號,用老師編號在課程表查詢該老師教授的課程編號,通過課程編號在成績表中查詢沒有該課程成績的學生編號,最后通過學生編號在學生表中得出這些同學的學號姓名
關鍵函數:where、in
解題語句1:
SELECT s_id,s_name FROM student WHERE s_id NOT IN( SELECT s_id FROM score WHERE c_id = (SELECT c_id FROM course WHERE t_id= (SELECT t_id FROM teacher WHERE t_name = '張三')))結果:
思路2:成績和課程表通過課程編號內連接,再與學生成績表通過學生編號進行內連接。篩選處有‘張三’的課程成績的學生編號,在學生表中選出學生編號不在上面選中的學生編號的學生姓名編號和姓名
關鍵函數:inner jion 、not in
解題語句2:
SELECT s_id,s_name FROM student WHERE s_id NOT IN( SELECT a.s_id FROM score AS a INNER JOIN course AS c ON c.c_id=a.c_id INNER JOIN teacher AS d ON d.t_id=c.t_id WHERE d.t_name='張三')結果:
-- 6、查詢學過“張三”老師所教的所有課的同學的學號、姓名
理解1:學過張三老師的課的學生信息
思路:構建一張表包含:學生學號、學生姓名、課程成績、課程老師。再通過老師姓名篩選
用分組去重(雖然本題沒有重復結果)
關鍵函數:inner jion
解題語句:
SELECT st.s_id,st.s_name FROM student AS st INNER JOIN score AS s ON st.s_id=s.s_id INNER JOIN course AS c ON s.c_id=c.c_id INNER JOIN teacher AS t ON t.t_id=c.t_id WHERE t.t_name ='張三' GROUP BY st.s_id結果:
理解2:學了張三老師所有課的學生信息
思路:構建一張表包含:學生學號、學生姓名、課程成績、課程老師。通過老師姓名篩選。再選出學生所選課程數等于張三老師所教的課程數的學生信息
解題語句:
SELECT st.s_id,st.s_name FROM student AS st INNER JOIN score AS s ON st.s_id=s.s_id INNER JOIN course AS c ON s.c_id=c.c_id INNER JOIN teacher AS t ON t.t_id=c.t_id WHERE t.t_name ='張三' GROUP BY st.s_id HAVING COUNT(st.s_id) IN (SELECT COUNT(c_name) FROM course INNER JOIN teacher ON course.t_id=teacher.t_id WHERE teacher.t_name='張三')結果:
-- 7、查詢學過編號為“01”的課程并且也學過編號為“02”的課程的學生的學號、姓名
思路1:通過內連接將成績表課程‘01’和課程‘02’的信息相連接得出新表,從學生表中獲取學生編號在新表中的學生標號和姓名
關鍵函數:inner jion、in
解題語句1:
SELECT s_id,s_name FROM student WHERE s_id IN ( SELECT a.s_id FROM (SELECT s_id FROM score WHERE c_id='01')AS a INNER JOIN (SELECT s_id FROM score WHERE c_id='02')AS b ON a.s_id=b.s_id )結果:
思路2:在學生表中選出滿足兩個條件的學生學號和學生姓名,條件1:有課程編號‘01’成績的學生編號,條件2:有課程編號‘02’成績的學生編號
關鍵函數:WHERE...IN...AND
解題語句2:
SELECT s_id,s_name FROM student WHERE s_id IN (SELECT s_id FROM score WHERE c_id='01') AND s_id IN (SELECT s_id FROM score WHERE c_id='02')結果:
-- 8、查詢各門的總成績、平均成績和人數
關鍵函數:sum、avg、count
解題語句:
SELECT c_id '課程編號',SUM(s_score) '總成績', AVG(s_score ) '平均成績',COUNT(s_score) '人數' FROM score GROUP BY c_id結果:
-- 9、查詢所有課程成績小于60分的學生的學號、姓名
思路:得出各同學課程成績小于60分的課程數,統計各同學共學了幾門課,選出二者相等的學生學號、姓名
關鍵函數:group_by、inner jion
解題語句:
SELECT a.s_id,t.s_name FROM ( SELECT s_id,COUNT(c_id) 'count' FROM score WHERE s_score<60 GROUP BY s_id )AS a INNER JOIN ( SELECT s_id,COUNT(c_id) 'count' FROM score GROUP BY s_id )AS b ON a.s_id=b.s_id INNER JOIN student AS t ON a.s_id=t.s_id WHERE a.count=b.count結果:
-- 10、查詢沒有學全所有課的學生的學號、姓名
思路:將學生與成績表通過學生學號左連接,計算每個學生的成績數,選出小于課程總數的學生學號和姓名
關鍵函數:group_by、count、distinct、left jion
解題語句:
SELECT st.s_id '學生學號',st.s_name '學生姓名' FROM student AS st LEFT JOIN score AS sc ON st.s_id=sc.s_id GROUP BY st.s_id HAVING COUNT(DISTINCT sc.c_id)<(SELECT count(DISTINCT c_id) FROM course)結果:
-- 11、查詢至少有一門課程與學號為“01”的學生所學課程相同的其他同學的學號
思路:選出課程與‘01’學生學過的課程相同的學生學號,去重,去掉‘01’同學
關鍵函數:in、and
解題語句:
SELECT s_id,s_name FROM student WHERE s_id in ( SELECT DISTINCT s_id FROM score WHERE c_id in ( SELECT c_id FROM score WHERE s_id='01' ) AND s_id!='01' )結果:
-- 12、查詢和“01”號同學所學課程完全相同的其他同學的學號
思路1:將學號不為‘01’的學生課程編號連接形成新的字段,選出與學號為‘01’的學生課程編號連接形成字段相同的學生學號
關鍵函數:group_concat、group by
解題語句1:
SELECT s_id FROM score WHERE s_id <>'01' GROUP BY s_id HAVING GROUP_CONCAT(c_id)=( SELECT GROUP_CONCAT(c_id) FROM score WHERE s_id='01')結果:
思路2:將學號不為‘01’的學生成績表左連接學號為‘01’的學生成績表,計算每一個學號不為‘01’的學生課程數,選出課程數和‘01’學生相同的學生學號
關鍵函數:left jion、group_by、count
解題語句:
SELECT a.s_id FROM (SELECT * FROM score WHERE s_id!='01') AS a LEFT JOIN(SELECT * FROM score WHERE s_id='01')AS b ON a.c_id=b.c_id GROUP BY a.s_id HAVING COUNT(b.s_id)=(SELECT COUNT(c_id) FROM score WHERE s_id='01')結果:
-- 15、查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
思路:成績表和學生表通過學生學號關聯得,查詢學號滿足以下:選出成績表中小于60分的成績,再通過學生學號分組,最后選出此表中大于一門成績的學生生學號。
關鍵函數:AVG,INNER JOIN ,GROUP BY,COUNT
解題語句:
SELECT a.s_id,a.s_name,AVG(b.s_score) FROM student AS a INNER JOIN score AS b ON a.s_id=b.s_id WHERE a.s_id IN (SELECT s_id FROM score AS a WHERE s_score<60 GROUP BY s_id HAVING COUNT(s_score)>1) GROUP BY a.s_id結果:
-- 16、檢索"01"課程分數小于60,按分數降序排列的學生信息
思路:學生表和成績表通過學生學號鏈接,用課程編號為‘01’和課程成績小于60兩個條件篩選,最后通過分數降序
關鍵函數:INNER JOIN,ORDER BY , DESC
解題語句:
SELECT * FROM student AS a INNER JOIN score AS b ON a.s_id=b.s_id WHERE b.c_id='01' AND b.s_score<60 ORDER BY b.s_score DESC結果:
-- 17、按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
思路:用avg計算平均成績,按照學生學號進行分組排序,利用max來顯示每一門課的成績(max函數沒有實際意義,只是用來顯示),用case when(課程編號為‘01’,輸出成績,否則輸出null)得到每一門的課程成績
關鍵函數:GROUP BY、ORDER BY、CASE WHEN THEN ELSE
解題語句:
SELECT s_id, MAX(CASE WHEN c_id='01' THEN s_score ELSE NULL END)'01', MAX(CASE WHEN c_id='03' THEN s_score ELSE NULL END)'02', MAX(CASE WHEN c_id='02' THEN s_score ELSE NULL END)'03', AVG(s_score) FROM score GROUP BY s_id ORDER BY AVG(s_score) DESC結果:
-- 18、查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
-- 及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90
思路:課程表和成績表通過課程編號鏈接,通過課程編號分組,取出課程編號、課程名、最高分、最低分和平均分。將是否滿足條件的分數通過case when函數變成01變量,求和便是符合條件的學生數,除以參與這一門考試的學生總數,便是各個分數段的概率
關鍵函數:group by,sum,case when ,count,max,min,avg,inner jion
解題語句:
SELECT b.c_id,b.c_name, MAX(a.s_score)'最高分',MIN(a.s_score)'最低分',AVG(a.s_score)'平均分', SUM(CASE WHEN a.s_score>=60 THEN 1 ELSE 0 END)/COUNT(a.s_id)'及格率', SUM(CASE WHEN a.s_score>=70 AND a.s_score<80 THEN 1 ELSE 0 END)/COUNT(a.s_id)'中等率', SUM(CASE WHEN a.s_score>=80 AND a.s_score<90 THEN 1 ELSE 0 END)/COUNT(a.s_id)'優良率', SUM(CASE WHEN a.s_score>=90 THEN 1 ELSE 0 END)/COUNT(a.s_score)'優秀率' FROM score AS a INNER JOIN course AS b ON a.c_id=b.c_id GROUP BY a.c_id結果:
-- 19、按各科成績進行排序,并顯示排名
關鍵函數:rank()
解題語句:
SELECT s_score,rank() over(PARTITION by s_id ORDER BY s_score DESC) FROM score;-- 20、查詢學生的總成績并進行排名
關鍵函數:sum、group by、order by
解題語句:
SELECT *,SUM(s_score) FROM score GROUP BY s_id ORDER BY SUM(s_score) DESC結果:
-- 21 、查詢不同老師所教不同課程平均分從高到低顯示
思路:成績表通過課程編號和課程表進行連接為了獲得課程名,再通過老師編號和教師表進行連接為了獲得老師名,通過課程編號或者課程名字進行分組,輸出課程編號、課程名、教師名、平均分,最后按照平均分排序
關鍵函數:avg、INNER JOIN、GROUP BY、ORDER BY
解題語句:
SELECT a.c_id,b.c_name,c.t_name,AVG(a.s_score) FROM score AS a INNER JOIN course AS b ON a.c_id=b.c_id INNER JOIN teacher AS c ON b.t_id=c.t_id GROUP BY a.c_id ORDER BY AVG(a.s_score) DESC結果:
-- 22、查詢所有課程的成績第2名到第3名的學生信息及該課程成績
思路:學生表和成績表通過課程編號相連接,通過row_number函數增加一列課程成績在該課程的排名,最后通過子查詢篩選出排名,即增加的排名列數字為2,3的數據
關鍵函數:row_number、ORDER BY、INNER JOIN
解題語句:
SELECT * FROM ( SELECT b.s_id,b.s_name,b.s_birth,,b.s_sex,a.c_id,a.s_score, row_number()over(PARTITION by a.c_id ORDER BY a.s_score DESC) m FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id ) WHERE m IN(2,3)-- 23、使用分段[100-85],[85-70],[70-60],[<60]來統計各科成績,分別統計各分數段人數:課程ID和課程名稱
思路:通過課程編號將成績表和課程表連接,再通過課程編號分組,得出課程成績和課程編號,通過case when函數將每個分數段的人數轉換為0/1或者1/null 形式,通過sum(0/1)或者count(1/null)得出每個分數段的人數
關鍵函數:SUM/COUNT、case when、inner jion
解題語句:
SELECT a.c_id,b.c_name, SUM(CASE WHEN a.s_score<60 THEN 1 ELSE 0 END) '不及格', SUM(CASE WHEN a.s_score>=60 AND a.s_score<70 THEN 1 ELSE 0 END) '及格', COUNT(CASE WHEN a.s_score>=70 AND a.s_score<85 THEN 1 ELSE NULL END) '良', COUNT(CASE WHEN a.s_score>=85 THEN 1 ELSE NULL END) '優' FROM score AS a INNER JOIN course AS b ON a.c_id=b.c_id GROUP BY a.c_id結果:
-- 24、查詢學生平均成績及其名次
關鍵函數:rank
解題語句:
SELECT s_id,AVG(s_score),rank() over(PARTITION by s_id ORDER BY AVG(s_score)DESC) FROM score-- 25、查詢各科成績前三名的記錄(不考慮成績并列情況)
思路:學生表和成績表通過課程編號相連接,通過row_number函數增加一列課程成績在該課程的排名,最后通過子查詢篩選出排名,即增加的排名列數字為1,2,3的數據
關鍵函數:row_number、ORDER BY、INNER JOIN
解題語句:
SELECT * FROM (SELECT b.s_id,b.s_name,b.s_birth,,b.s_sex,a.c_id,a.s_score, row_number()over(PARTITION by a.c_id ORDER BY a.s_score DESC) m FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id ) a WHERE m IN(1,2,3)-- 26、查詢每門課程被選修的學生數
解題語句:
SELECT c_id,COUNT(c_id) FROM score GROUP BY c_id結果:
-- 27、查詢出只有兩門課程的全部學生的學號和姓名
思路1:通過學生學號將成績表和學生表連接,通過學生學號分組,計算學生選課成績的數量,用having篩選出數量為2的信息,輸出學生學號和姓名
關鍵函數:LEFT JOIN、GROUP BY、HAVING、COUNT
解題語句1:
SELECT a.s_id,b.s_name,COUNT(a.c_id) FROM score AS a LEFT JOIN student AS b ON a.s_id=b.s_id GROUP BY a.s_id HAVING COUNT(a.c_id)=2結果:
思路2:成績表通過學生學號分組,選出選課成績為2的學生學號;通過子查詢,在學生表中去的學生學號和姓名
關鍵函數:GROUP BY
解題語句2:
SELECT s_id,s_name FROM student WHERE s_id IN( (SELECT s_id FROM score GROUP BY s_id HAVING COUNT(c_id)=2) )結果:
-- 28、查詢男生、女生人數
思路1:通過性別進行分組,計算每個性別人數
關鍵函數:GROUP BY、count
解題語句:
SELECT s_sex,COUNT(s_sex) FROM student GROUP BY s_sex結果:
思路2:將性別變成01變量,通過sum/count得出每個性別人數
關鍵函數:case when、count、sum
解題語句:
SELECT SUM(CASE WHEN s_sex='男' THEN 1 ELSE 0 END)'男生個數', count(CASE WHEN s_sex='女' THEN 1 ELSE NULL END) '女生個數' FROM student結果:
?
-- 29 查詢名字中含有"風"字的學生信息
思路:用like進行字符串匹配
關鍵函數:like
解題語句:
SELECT * FROM student WHERE s_name LIKE '%風%'結果:
?
-- 31、查詢1990年出生的學生名單
思路1:用like進行字符串匹配的方法得到出生日期為1990年
關鍵函數:like
解題語句:
SELECT * FROM student WHERE s_birth LIKE '1990%'結果:
思路2:用year函數去除日期中的年份,篩選出1990年的數據
關鍵函數:year
解題語句:
SELECT * FROM student WHERE YEAR(s_birth)=1990結果:
-- 32、查詢平均成績大于等于85的所有學生的學號、姓名和平均成績
關鍵函數:INNER JOIN...ON、GROUP BY...HAVING
解題語句:
SELECT a.s_id,a.s_name,AVG(b.s_score) FROM student AS a INNER JOIN score AS b ON a.s_id=b.s_id GROUP BY b.s_id HAVING AVG(b.s_score)>=85結果:
-- 33、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列
關鍵函數:avg、select...from...group by...order by ...,...
解題語句:
SELECT c_id,AVG(s_score) FROM score GROUP BY c_id ORDER BY AVG(s_score),c_id DESC結果:
-- 34、查詢課程名稱為"數學",且分數低于60的學生姓名和分數
思路:將學生表(需要學生姓名)、成績表(需要數學成績)、課程表(需要課程名)連接起來篩選即可
關鍵函數:left jion....on
解題語句:
SELECT a.s_name,b.s_score FROM student AS a LEFT JOIN score AS b ON a.s_id=b.s_id LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c.c_name='數學' AND b.s_score<60結果:
?
-- 35、查詢所有學生的課程及分數情況
思路1:需要形成的新表包括學生學號、學生姓名、各科成績。將學生表左連接各科成績表,各科成績表通過將成績表和課程表用課程編號連接后用課程名篩選后得出
關鍵函數:SELECT... FROM...LEFT JOIN...ON...
解題語句1:
SELECT a.s_id'學號',a.s_name'姓名',d.s_score'語文',e.s_score'數學',f.s_score'英語' FROM student AS a LEFT JOIN (SELECT b.s_id,c.c_name,b.s_score FROM score AS b LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='語文')AS d ON a.s_id=d.s_id LEFT JOIN (SELECT b.s_id,c.c_name,b.s_score FROM score AS b LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='數學')AS e ON a.s_id=e.s_id LEFT JOIN (SELECT b.s_id,c.c_name,b.s_score FROM score AS b LEFT JOIN course AS c ON b.c_id=c.c_id WHERE c_name='英語')AS f ON a.s_id=f.s_id結果:
思路2:成績表通過學生編號和學生表連接再通過課程編號和課程表連接,通過學生編號進行分組,通過case when輸出各科成績,判斷課程名稱并輸出,由于輸出只會輸出第一條判斷情況,所以用sum或者max
關鍵函數:MAX(CASE WHEN...THEN...ELSE NULL END)、SELECT... FROM...INNER JOIN...ON...
解題語句2:
SELECT c.s_id,c.s_name, MAX(CASE WHEN b.c_name='語文' THEN a.s_score ELSE NULL END)'語文', MAX(CASE WHEN b.c_name='數學' THEN a.s_score ELSE NULL END)'數學', MAX(CASE WHEN b.c_name='英語' THEN a.s_score ELSE NULL END)'英語' FROM score AS a INNER JOIN course AS b ON a.c_id=b.c_id INNER JOIN student AS c ON a.s_id=c.s_id GROUP BY c.s_id結果:
-- 36、查詢課程成績在70分以上的學生姓名、課程名稱和分數
思路:將學生表成績表課程表相連接
關鍵函數:SELECT... FROM...LEFT JOIN...ON...WHERE...
解題語句:
SELECT a.s_name,c.c_name,b.s_score FROM student AS a LEFT JOIN score AS b ON a.s_id=b.s_id LEFT JOIN course AS c ON b.c_id=c.c_id WHERE b.s_score>70結果:
-- 37、查詢不及格的課程并按課程號從大到小排列
關鍵函數:SELECT... FROM...INNER JOIN...ON...WHERE...ORDER BY...DESC
解題語句:
SELECT a.s_id,b.s_name,a.c_id,a.s_score FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id WHERE a.s_score<60 ORDER BY a.c_id DESC結果:
--?38、查詢課程編號為03且課程成績在80分以上的學生的學號和姓名
關鍵函數:SELECT... FROM...INNER JOIN...ON...WHERE...AND...
解題語句:
SELECT a.s_id,b.s_name,a.s_score FROM score AS a INNER JOIN student AS b ON a.s_id=b.s_id WHERE a.s_score>80 AND a.c_id='03'結果:
-- 39、求每門課程的學生人數
解題語句:
SELECT c_id,COUNT(s_score) FROM score GROUP BY c_id結果:
-- 40、查詢選修“張三”老師所授課程的學生中成績最高的學生姓名及其成績
思路:用窗口函數,rank
?
-- 41.查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
思路:從成績表中通過用學生學號分組計算課程成績數來選出至少學了有兩門課的學生與成績表內連接再通過學生學號和成績分組篩選只有一個數據的學生學號
關鍵函數:INNER JOIN、GROUP BY、HAVING、COUNT(DISTINCT ...)
解題語句:
SELECT s_id FROM (SELECT a.s_id,a.s_score FROM score AS a INNER JOIN (SELECT s_id FROM score GROUP BY s_id HAVING COUNT(DISTINCT c_id)>1)AS b ON a.s_id=b.s_id GROUP BY a.s_id,a.s_score )AS c GROUP BY s_id HAVING COUNT(s_id)=1結果:
-- 43、統計每門課程的學生選修人數(超過5人的課程才統計)。
-- 要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
關鍵函數:COUNT()、GROUP BY、HAVING、ORDER BY
解題語句:
SELECT c_id,COUNT(s_score) FROM score GROUP BY c_id HAVING COUNT(s_score)>5 ORDER BY COUNT(s_score) DESC,c_id結果:
-- 44、檢索至少選修兩門課程的學生學號和選課數
關鍵函數:COUNT()、GROUP BY、HAVING
解題語句:
SELECT s_id,COUNT(s_score) FROM score GROUP BY s_id HAVING COUNT(s_score)>=2結果:
-- 45、 查詢選修了全部課程的學生信息
思路:由于要獲得學生信息就通過學生學號將學生表和成績表連接,將新表通過學生學號進行分組,篩選條件為學生課程數等于課程表中的課程數
關鍵函數:LEFT JOIN、GROUP BY、COUNT(DISTINCT ...)
解題語句:
SELECT * FROM student AS a LEFT JOIN score AS b ON a.s_id=b.s_id GROUP BY a.s_id HAVING COUNT(DISTINCT c_id) =( SELECT COUNT(c_id) FROM course)結果:
-- 46、查詢各學生的年齡(精確到月份)
關鍵函數:DATEDIFF()
解題語句:
SELECT s_id,s_birth,DATEDIFF('2020-5-20',s_birth)/365 FROM student結果:
?
-- 50、查詢下個月過生日的學生
思路:用now()獲得現在的時間month取出現在的月份,生日的月份等于通過round取余數加一則是下周過生日
關鍵函數:=MONTH()、date()、NOW()、%
解題語句:
SELECT * FROM student WHERE MONTH(s_birth)=MONTH(date(NOW()))%12+1結果:
知識點:
1.inner jion、right jion、left jion的區別
inner join為“有效的連接”,就是根據on后面的關聯條件,兩張表中都有的數據才會顯示
left join為主表全顯示,連接后的表看on后面的選擇條件,left join后面的條件,并不會影響左表的數據顯示,左表數據會全部顯示出來,連接的表如果沒有數據,則全部顯示為null
right join為“主表看on,后表全顯”(右表數據不受影響),即右表數據全部顯示,主表數據看on后面的選擇條件
?
2.字符匹配
_代表一個字符, %代表0個及以上字符
開頭是m m%
結尾是m %m
第二個字母為m _m%
非首字母字母有m _%m%
?
3.rank,dense_rank,row_number的區別
rank(跳躍排序)
分數 排名
92 1
82 2
82 2
67 4
dense_rank(連續排序)
分數 排名
92 1
82 2
82 2
67 3
row_number(無重復值排序)
分數 排名
92 1
82 2
82 3
67 4
?
語句表:
1、插入數據:
insert into?表名?values( )?#輸入的值要跟原表對應
insert into Teacher values('02' , '李四')
?
2、查詢表中的數據:
select?*?from?表名 # *號代表取全部列的數據
select * from student
?
select?指定列?from?表名
SELECT t_id,s_score FROM score
?
查詢表中數據的統計量:min、max、avg、count、sum,
select?avg(列名)?from?表名
SELECT c_id '課程編號',SUM(s_score) '總成績',AVG(s_score ) '平均成績',COUNT(s_score) '人數' FROM score
GROUP BY c_id
?
條件查詢:
select?指定列?from?表名?where?條件
SELECT?s_id?FROM?score?WHERE?s_id <>'01'
條件符號:
(1)>大于 ;<小于; =等于; <>和!=不等于
(2)like 字符匹配 select?*?from?teacher?where?t_name?like?'張%'
(3)between...and 區間 SELECT?*?FROM?score?WHERE?s_score?BETWEEN?70?AND?90
(4)in 指定數據集作為條件,也常用于子查詢
?
3、GROUP BY 語句
根據一個或多個列對結果集進行分組,分組后的輸出的統計量是每一組的統計量
SELECT?列名或統計量?FROM?表名?GROUP BY?列名
SELECT c_id,SUM(s_score),AVG(s_score ),COUNT(s_score)
FROM score
GROUP BY c_id
?
GROUP BY后的條件查詢用having
?
4、ORDER BY 語句
排序
SELECT *,SUM(s_score) FROM score GROUP BY s_id ORDER BY SUM(s_score) DESC
?
5、year、month、day、now語句
用來從日期中提取需要的年/月/日
SELECT?*?FROM?student?WHERE?YEAR(s_birth)=1990;
SELECT?*?FROM?student?WHERE MONTH(s_birth)=01;
SELECT?*?FROM?student?WHERE DAY(s_birth)='01';
條件可以用數字或者字符串
日期類型可以是YYYY-MM-DD、YYYYMMDD、YYYY/MM/DD
2020-05-20、20200520、2020/05/20
注意:對于YYYYMMDD這種格式日期,0不能少,一月份必須是01不能是1,但年份可以是后兩位,即格式為YYMMDD
now()
獲得當前時間有時分秒
?
6、LIMIT語句
用于選取第幾行數據,SQL從0開始計數
SELECT?c_id?FROM?score
LIMIT 0,1?#表示從0開始(第一行開始),選取第一行數據
?
7、DATEDIFF語句
用于計算日期間隔
SELECT s_id,s_birth,DATEDIFF('2020-5-20',s_birth)/365 FROM student
?
?
總結
以上是生活随笔為你收集整理的学生表 成绩表 课程表 教师表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++:最小二乘法拟合直线
- 下一篇: 地震频繁