MySQL練習:復雜的SQL語句


MySQL練習:復雜的SQL語句

 

2021-8-1這一周鞏固、拓展了一下MySQL技能。

 

1. 練習環境創建:

本練習使用的是MySQL 5.6,與MySQL 8可能有不兼容。

1.1  數據庫的4個表:

課程表course, 成績表sc, 學生表student, 教師表teacher。

 

 

1.2 課程表course,

 

 

1.3 成績表sc,

 

 

1.4 學生表student,

 

 

1.5 教師表teacher。

 

 

 

 

2. 實例

例1.  創建課程情況匯總表

匯總表欄目包括課程ID,課程名稱,選學人數,合格人數,不合格人數,平均成績,通過率,各分數段人數。

要點:在聚合函數內加條件。

select 
    sc.cid as `課程ID`, 
    course.cname as `課程名稱`,
    count(1) as `選學人數`,
    count(case when score < 60 then null else 1 end) as `合格人數`,
    count(case when score < 60 then 1 else null end) as `不合格人數`,
    round(avg(score)) as `平均成績`,
    round(count(case when score < 60 then null else 1 end) / count(1), 2) as `通過率`,
    sum(case when score>= 85 then 1 else 0 end) as `100 - 85`,
    sum(case when score>= 70 and score< 85 then 1 else 0 end) as `85 - 70`,
    sum(case when score>= 60 and score<70 then 1 else 0 end) as `70 - 60`,
    sum(case when score< 60 then 1 else 0 end) as `60 - 0`
from sc, course
where sc.Cid = course.Cid
group by sc.Cid;

查詢結果:

 

 

例2. 學生成績排名表

查詢結果包含的欄目是:學號、姓名、平均成績、排名。

要點:實現並列排名,這里用到了兩個內容一樣的臨時表t1, t2。

注意這里的rank不加引號在MySQL 8可能運行異常,因為MySQL 8有rank()排名函數。可以直接使用MySQL 8的rank()函數完成排名。

select t2.sid, 
    student.sname,
    t2.average,
    1+(select count(average) from 
        (
            select sid, avg(score) as average
            from sc
            group by sid
        ) as t1
        where average > t2.average
    ) as ·rank·
from
    student,
    (
        select sid, avg(score) as average
        from sc
        group by sid
    ) as t2
where t2.sid = student.sid
order by average desc;

查詢結果:

 

 MySQL 8.0寫法:

select t2.sid, 
    student.sname,
    t2.average,
    rank() over(order by t2.average desc) as ·rank·
from
    student,
    (
        select sid, avg(score) as average
        from sc
        group by sid
    ) as t2
where t2.sid = student.sid
order by average desc;

 

 

 

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

寫法1:

SELECT Sid,Sname FROM student 
WHERE (SELECT Sid FROM sc WHERE Cid=001 and Sid = student.Sid) 
AND (SELECT Sid FROM sc WHERE Cid=002 and Sid = student.Sid);

寫法2:

SELECT Sid,Sname FROM student 
WHERE Sid IN (SELECT Sid FROM sc WHERE Cid=001) 
AND Sid IN (SELECT Sid FROM sc WHERE Cid=002);

 

例4. 查詢“001”課程比“002”課程成績高的所有學生的學號、及相應的成績

要點:先形成臨時匯總表,然后加上兩門課程分數比較的條件。

SELECT * FROM 
(
    select sc.sid, student.sname,
    sum(case cid when 001 then score else null end) as course001,
    sum(case cid when 002 then score else null end) as course002
    from sc join student on sc.sid = student.sid
    group by sid
) as temptable
where course001 > course002;

 

 

如果不需要兩門課程的成績,SQL語句可以簡化為:

SELECT Sid,Sname FROM student 
WHERE (SELECT score FROM sc WHERE Cid=001 and Sid = student.Sid) > (SELECT score FROM sc WHERE Cid=002 and Sid = student.Sid);

或者寫作:

SELECT student.Sid, student.Sname from sc as scout join student on scout.sid = student.sid
WHERE Cid = 001  AND score > (SELECT score FROM sc as scin WHERE scout.Sid = scin.Sid and Cid = 002);

 

 

例5. 查詢每門課程的最高分學生

查詢過程:

先產生“每門課程最高分”臨時表t1;

然后,聯合成績表sc,查詢出每門課程的最高分記錄,作為臨時表t2;

最后,聯合學生表、課程表添加學生名字、課程名稱。

select t2.cid, course.Cname, t2.sid, student.sname, t2.score 
from
    student, 
    course, 
    (
        select sc.*
        from (select cid, max(score) as topscore from sc group by cid) as t1
        join sc
        on sc.Cid = t1.cid and sc.score = t1.topscore
    ) as t2
where student.sid = t2.sid and t2.cid=course.cid
order by cid;

 

 

例6. 學過“葉平”老師課的同學的學號、姓名

本例同時用到學生、老師、課程、評分4個表。

要點:整理好SQL語句的層次關系。

SELECT Sid,Sname FROM student
WHERE Sid IN 
(
    SELECT DISTINCT Sid
    FROM 
        sc,
        (
            SELECT Cid 
            FROM course 
            WHERE Tid IN (SELECT Tid FROM teacher WHERE Tname = '葉平')
        ) AS courseofteacher
    WHERE courseofteacher.Cid=sc.Cid
);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM