數據庫多表查詢之練習

CREATE DATABASE javacto;
USE javacto;

#班級表
CREATE TABLE class(
	cid INT PRIMARY KEY,
	caption VARCHAR(6)
);

#老師表:teacher
CREATE TABLE teacher(
	tid INT PRIMARY KEY,
	tname VARCHAR(8) NOT NULL
);
#學生表
CREATE TABLE student(
	sid INT PRIMARY KEY,
	sname VARCHAR(8) NOT NULL,
	gender VARCHAR(2) NOT NULL,
	class_id INT NOT NULL
);

#課程表 course

CREATE TABLE course(
	cid INT PRIMARY KEY,
	cname VARCHAR(8) NOT NULL,
	teacher_id INT NOT NULL,
	FOREIGN KEY(teacher_id) REFERENCES teacher(tid)
);


#成績表
CREATE TABLE score(
	sid  INT PRIMARY KEY,
	student_id INT NOT NULL,
	scorse_id INT NOT NULL,
	number INT NOT NULL,
	FOREIGN KEY(student_id) REFERENCES student(sid),
	FOREIGN KEY(scorse_id) REFERENCES course(cid)
);

#建庫建表


1、自行創建測試數據

2、查詢“生物”課程比“物理”課程成績高的所有學生的學號;

3、查詢平均成績大於60分的同學的學號和平均成績; 

  SELECT student_id,AVG(number) FROM score GROUP BY student_id HAVING AVG(number)>60;

  問題:很明顯是平均之後進行比較(用HAVING),出現HAVING之後必須在前有GROUP BY;

4、查詢所有同學的學號、姓名、選課數、總成績;

  SELECT student.sid,student.sname,COUNT(scorse_id),SUM(number)FROM student LEFT JOIN score ON student.sid=score.student_id GROUP BY student.sid

5、查詢姓“李”的老師的個數;

  問題:LIKE模糊匹配不清楚

  SELECT COUNT(tid) FROM teacher WHERE tname LIKE '李%';

6、查詢沒學過“葉平”老師課的同學的學號、姓名;

7、查詢學過“001”並且也學過編號“002”課程的同學的學號、姓名;

8、查詢學過“葉平”老師所教的所有課的同學的學號、姓名;

9、查詢課程編號“002”的成績比課程編號“001”課程低的所有同學的學號、姓名;

10、查詢有課程成績小於60分的同學的學號、姓名;

11、查詢沒有學全所有課的同學的學號、姓名;

12、查詢至少有一門課與學號爲“001”的同學所學相同的同學的學號和姓名;

13、查詢至少學過學號爲“001”同學所選課程中任意一門課的其他同學學號和姓名;

14、查詢和“002”號的同學學習的課程完全相同的其他同學學號和姓名;

15、刪除學習“葉平”老師課的SC表記錄;

16、向SC表中插入一些記錄,這些記錄要求符合以下條件:①沒有上過編號“002”課程的同學學號;②插入“002”號課程的平均成績; 

17、按平均成績從低到高顯示所有學生的“語文”、“數學”、“英語”三門的課程成績,按如下形式顯示: 學生ID,語文,數學,英語,有效課程數,有效平均分;

18、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分;

19、按各科平均成績從低到高和及格率的百分數從高到低順序;

20、課程平均分從高到低顯示(現實任課老師);

21、查詢各科成績前三名的記錄:(不考慮成績並列情況) 

22、查詢每門課程被選修的學生數;

23、查詢出只選修了一門課程的全部學生的學號和姓名;

24、查詢男生、女生的人數;

25、查詢姓“張”的學生名單;

26、查詢同名同姓學生名單,並統計同名人數;

27、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;

28、查詢平均成績大於85的所有學生的學號、姓名和平均成績;

29、查詢課程名稱爲“數學”,且分數低於60的學生姓名和分數;

30、查詢課程編號爲003且課程成績在80分以上的學生的學號和姓名; 

31、求選了課程的學生人數

32、查詢選修“楊豔”老師所授課程的學生中,成績最高的學生姓名及其成績;

33、查詢各個課程及相應的選修人數;

34、查詢不同課程但成績相同的學生的學號、課程號、學生成績;

35、查詢每門課程成績最好的前兩名;

36、檢索至少選修兩門課程的學生學號;

37、查詢全部學生都選修的課程的課程號和課程名;

38、查詢沒學過“葉平”老師講授的任一門課程的學生姓名;

39、查詢兩門以上不及格課程的同學的學號及其平均成績;

40、檢索“004”課程分數小於60,按分數降序排列的同學學號;

41、刪除“002”同學的“001”課程的成績;

更多學習資料:javacto.taobao.com

#答案下面  


2、查詢“生物”課程比“物理”課程成績高的所有學生的學號;
思路:
    獲取所有有生物課程的人(學號,成績) - 臨時表
    獲取所有有物理課程的人(學號,成績) - 臨時表
    根據【學號】連接兩個臨時表:
        學號  物理成績   生物成績

    然後再進行篩選

        SELECT A.student_id,sw,ty FROM 

        (SELECT student_id,num AS sw FROM score LEFT JOIN course ON score.course_id = course.cid WHERE course.cname = '生物') AS A

        LEFT JOIN 

        (SELECT student_id,num  AS ty FROM score LEFT JOIN course ON score.course_id = course.cid WHERE course.cname = '體育') AS B

        ON A.student_id = B.student_id WHERE sw > IF(ISNULL(ty),0,ty);

3、查詢平均成績大於60分的同學的學號和平均成績; 
    思路:
        根據學生分組,使用AVG獲取平均值,通過HAVING對AVG進行篩選

        SELECT student_id,AVG(num) FROM score GROUP BY student_id HAVING AVG(num) > 60

4、查詢所有同學的學號、姓名、選課數、總成績;

    SELECT score.student_id,SUM(score.num),COUNT(score.student_id),student.sname 
    FROM 
        score LEFT JOIN student ON score.student_id = student.sid   
    GROUP BY score.student_id

5、查詢姓“李”的老師的個數;
    SELECT COUNT(tid) FROM teacher WHERE tname LIKE '李%'

    SELECT COUNT(1) FROM (SELECT tid FROM teacher WHERE tname LIKE '李%') AS B

6、查詢沒學過“葉平”老師課的同學的學號、姓名;
    思路:
        先查到“李平老師”老師教的所有課ID
        獲取選過課的所有學生ID
        學生表中篩選
    SELECT * FROM student WHERE sid NOT IN (
        SELECT DISTINCT student_id FROM score WHERE score.course_id IN (
            SELECT cid FROM course LEFT JOIN teacher ON course.teacher_id = teacher.tid WHERE tname = '李平老師'
        )
    )

7、查詢學過“001”並且也學過編號“002”課程的同學的學號、姓名;
    思路:
        先查到既選擇001又選擇002課程的所有同學
        根據學生進行分組,如果學生數量等於2表示,兩門均已選擇

    SELECT student_id,sname FROM 

    (SELECT student_id,course_id FROM score WHERE course_id = 1 OR course_id = 2) AS B
     
    LEFT JOIN student ON B.student_id = student.sid GROUP BY student_id HAVING COUNT(student_id) > 1


8、查詢學過“葉平”老師所教的所有課的同學的學號、姓名;

    同上,只不過將001和002變成 IN (葉平老師的所有課)

9、查詢課程編號“002”的成績比課程編號“001”課程低的所有同學的學號、姓名;
    同第1題


10、查詢有課程成績小於60分的同學的學號、姓名;
        
    SELECT sid,sname FROM student WHERE sid IN (
        SELECT DISTINCT student_id FROM score WHERE num < 60
    )

11、查詢沒有學全所有課的同學的學號、姓名;
    思路:
        在分數表中根據學生進行分組,獲取每一個學生選課數量
        如果數量 == 總課程數量,表示已經選擇了所有課程

        SELECT student_id,sname 
        FROM score LEFT JOIN student ON score.student_id = student.sid 
        GROUP BY student_id HAVING COUNT(course_id) = (SELECT COUNT(1) FROM course)


12、查詢至少有一門課與學號爲“001”的同學所學相同的同學的學號和姓名;
    思路:
        獲取 001 同學選擇的所有課程
        獲取課程在其中的所有人以及所有課程
        根據學生篩選,獲取所有學生信息
        再與學生表連接,獲取姓名

        SELECT student_id,sname, COUNT(course_id) 
        FROM score LEFT JOIN student ON score.student_id = student.sid
        WHERE student_id != 1 AND course_id IN (SELECT course_id FROM score WHERE student_id = 1) GROUP BY student_id

13、查詢至少學過學號爲“001”同學所有課的其他同學學號和姓名;
        先找到和001的學過的所有人
        然後個數 = 001所有學科     ==》 其他人可能選擇的更多

        SELECT student_id,sname, COUNT(course_id) 
        FROM score LEFT JOIN student ON score.student_id = student.sid
        WHERE student_id != 1 AND course_id IN (SELECT course_id FROM score WHERE student_id = 1) GROUP BY student_id HAVING COUNT(course_id) = (SELECT COUNT(course_id) FROM score WHERE student_id = 1)

14、查詢和“002”號的同學學習的課程完全相同的其他同學學號和姓名;
        
        個數相同
        002學過的也學過

        SELECT student_id,sname FROM score LEFT JOIN student ON score.student_id = student.sid WHERE student_id IN (
            SELECT student_id FROM score  WHERE student_id != 1 GROUP BY student_id HAVING COUNT(course_id) = (SELECT COUNT(1) FROM score WHERE student_id = 1)
        ) AND course_id IN (SELECT course_id FROM score WHERE student_id = 1) GROUP BY student_id HAVING COUNT(course_id) = (SELECT COUNT(1) FROM score WHERE student_id = 1)


15、刪除學習“葉平”老師課的score表記錄;

    DELETE FROM score WHERE course_id IN (
        SELECT cid FROM course LEFT JOIN teacher ON course.teacher_id = teacher.tid WHERE teacher.name = '葉平'
    )

16、向SC表中插入一些記錄,這些記錄要求符合以下條件:①沒有上過編號“002”課程的同學學號;②插入“002”號課程的平均成績; 
    思路:
        由於INSERT 支持  
                inset INTO tb1(xx,xx) SELECT x1,x2 FROM tb2;
        所有,獲取所有沒上過002課的所有人,獲取002的平均成績

    INSERT INTO score(student_id, course_id, num) SELECT sid,2,(SELECT AVG(num) FROM score WHERE course_id = 2) 
    FROM student WHERE sid NOT IN (
        SELECT student_id FROM score WHERE course_id = 2
    )
    
17、按平均成績從低到高 顯示所有學生的“語文”、“數學”、“英語”三門的課程成績,按如下形式顯示: 學生ID,語文,數學,英語,有效課程數,有效平均分;
    SELECT sc.student_id,
        (SELECT num FROM score LEFT JOIN course ON score.course_id = course.cid WHERE course.cname = "生物" AND score.student_id=sc.student_id) AS sy,
        (SELECT num FROM score LEFT JOIN course ON score.course_id = course.cid WHERE course.cname = "物理" AND score.student_id=sc.student_id) AS wl,
        (SELECT num FROM score LEFT JOIN course ON score.course_id = course.cid WHERE course.cname = "體育" AND score.student_id=sc.student_id) AS ty,
        COUNT(sc.course_id),
        AVG(sc.num)
    FROM score AS sc
    GROUP BY student_id DESC         

18、查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分;
    
    SELECT course_id, MAX(num) AS max_num, MIN(num) AS min_num FROM score GROUP BY course_id;

19、按各科平均成績從低到高和及格率的百分數從高到低順序;
    思路:CASE WHEN .. THEN
    SELECT course_id, AVG(num) AS avgnum,SUM(CASE WHEN score.num > 60 THEN 1 ELSE 0 END)/COUNT(1)*100 AS percent FROM score GROUP BY course_id ORDER BY avgnum ASC,percent DESC;

20、課程平均分從高到低顯示(現實任課老師);

    SELECT AVG(IF(ISNULL(score.num),0,score.num)),teacher.tname FROM course 
    LEFT JOIN score ON course.cid = score.course_id 
    LEFT JOIN teacher ON course.teacher_id = teacher.tid

    GROUP BY score.course_id


21、查詢各科成績前三名的記錄:(不考慮成績並列情況) 
    SELECT score.sid,score.course_id,score.num,T.first_num,T.second_num FROM score LEFT JOIN 
    (
    SELECT 
        sid,
        (SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id ORDER BY num DESC LIMIT 0,1) AS first_num,
        (SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id ORDER BY num DESC LIMIT 3,1) AS second_num
    FROM 
        score AS s1
    ) AS T
    ON score.sid =T.sid
    WHERE score.num <= T.first_num AND score.num >= T.second_num

22、查詢每門課程被選修的學生數;
    
    SELECT course_id, COUNT(1) FROM score GROUP BY course_id;

23、查詢出只選修了一門課程的全部學生的學號和姓名;
    SELECT student.sid, student.sname, COUNT(1) FROM score

    LEFT JOIN student ON score.student_id  = student.sid

     GROUP BY course_id HAVING COUNT(1) = 1


24、查詢男生、女生的人數;
    SELECT * FROM 
    (SELECT COUNT(1) AS man FROM student WHERE gender='男') AS A ,
    (SELECT COUNT(1) AS feman FROM student WHERE gender='女') AS B 

25、查詢姓“張”的學生名單;
    SELECT sname FROM student WHERE sname LIKE '張%';

26、查詢同名同姓學生名單,並統計同名人數;

    SELECT sname,COUNT(1) AS COUNT FROM student GROUP BY sname;

27、查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列;
    SELECT course_id,AVG(IF(ISNULL(num), 0 ,num)) AS AVG FROM score GROUP BY course_id ORDER BY AVG     ASC,course_id DESC;

28、查詢平均成績大於85的所有學生的學號、姓名和平均成績;

    SELECT student_id,sname, AVG(IF(ISNULL(num), 0 ,num)) FROM score LEFT JOIN student ON score.student_id = student.sid GROUP BY student_id;

29、查詢課程名稱爲“數學”,且分數低於60的學生姓名和分數;

    SELECT student.sname,score.num FROM score 
    LEFT JOIN course ON score.course_id = course.cid
    LEFT JOIN student ON score.student_id = student.sid
    WHERE score.num < 60 AND course.cname = '生物'

30、查詢課程編號爲003且課程成績在80分以上的學生的學號和姓名; 
    SELECT * FROM score WHERE score.student_id = 3 AND score.num > 80

31、求選了課程的學生人數

    SELECT COUNT(DISTINCT student_id) FROM score

    SELECT COUNT(c) FROM (
        SELECT COUNT(student_id) AS c FROM score GROUP BY student_id) AS A

32、查詢選修“楊豔”老師所授課程的學生中,成績最高的學生姓名及其成績;
    
    SELECT sname,num FROM score 
    LEFT JOIN student ON score.student_id = student.sid
    WHERE score.course_id IN (SELECT course.cid FROM course LEFT JOIN teacher ON course.teacher_id = teacher.tid WHERE tname='張磊老師') ORDER BY num DESC LIMIT 1;

33、查詢各個課程及相應的選修人數;
    SELECT course.cname,COUNT(1) FROM score
    LEFT JOIN course ON score.course_id = course.cid
    GROUP BY course_id;


34、查詢不同課程但成績相同的學生的學號、課程號、學生成績;
    SELECT DISTINCT s1.course_id,s2.course_id,s1.num,s2.num FROM score AS s1, score AS s2 WHERE s1.num = s2.num AND s1.course_id != s2.course_id;

35、查詢每門課程成績最好的前兩名;

    SELECT score.sid,score.course_id,score.num,T.first_num,T.second_num FROM score LEFT JOIN 
    (
    SELECT 
        sid,
        (SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id ORDER BY num DESC LIMIT 0,1) AS first_num,
        (SELECT num FROM score AS s2 WHERE s2.course_id = s1.course_id ORDER BY num DESC LIMIT 1,1) AS second_num
    FROM 
        score AS s1
    ) AS T
    ON score.sid =T.sid
    WHERE score.num <= T.first_num AND score.num >= T.second_num

36、檢索至少選修兩門課程的學生學號;
    SELECT student_id FROM score GROUP BY student_id HAVING COUNT(student_id) > 1

37、查詢全部學生都選修的課程的課程號和課程名;
    SELECT course_id,COUNT(1) FROM score GROUP BY course_id HAVING COUNT(1) = (SELECT COUNT(1) FROM student);

38、查詢沒學過“葉平”老師講授的任一門課程的學生姓名;
    SELECT student_id,student.sname FROM score 
    LEFT JOIN student ON score.student_id = student.sid
    WHERE score.course_id NOT IN (
        SELECT cid FROM course LEFT JOIN teacher ON course.teacher_id = teacher.tid WHERE tname = '張磊老師'
    ) 
    GROUP BY student_id

39、查詢兩門以上不及格課程的同學的學號及其平均成績;

    SELECT student_id,COUNT(1) FROM score WHERE num < 60 GROUP BY student_id HAVING COUNT(1) > 2

40、檢索“004”課程分數小於60,按分數降序排列的同學學號;
    SELECT student_id FROM score WHERE num< 60 AND course_id = 4 ORDER BY num DESC;

41、刪除“002”同學的“001”課程的成績;
    DELETE FROM score WHERE course_id = 1 AND student_id = 2

更多學習資料:javacto.taobao.com

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章