mysql數據庫之聯表查詢


表准備:

這次我們用到5張表:

class表

student表

score表

course表

teacher表:

 

表結構模型

 

我們針對以下需求分析聯表查詢:

1、查詢所有的課程的名稱以及對應的任課老師姓名
2、查詢平均成績大於八十分的同學的姓名和平均成績
3、 查詢沒有報李平老師課的學生姓名
4、 查詢選修物理課程和體育課程其中一門的學生姓名
5、 查詢掛科超過兩門(包括兩門)的學生姓名和班級

6、找出同時選了李平老師所有課的學生班級和姓名

 

1、查詢所有的課程的名稱以及對應的任課老師姓名

分析需求:我們需要用到course和teacher表:既需要得到課程名稱又要拿到老師姓名,然后看表結構模型,我們可以知道course有外鍵字段teacher_id指向teacher表id,那么我們就可以用內連接inner join將兩張表拼接起來然后取其字段course.cname和teacher.tname即可得到我們想要的數據,SQL語句如下:

SELECT
    cname,
    tname 
FROM
    teacher
    INNER JOIN course ON course.teacher_id = teacher.tid;

 

2、查詢平均成績大於八十分的同學的姓名和平均成績

需求分析:我們需要用到score表和shtudent表,既要拿到學生姓名又要拿到成績,我們理所當然需要將這兩個表聯表或者做子連接,然后需求中需要用到平均數,那么我們應想到用聚合函數avg(),但使用聚合函數的前提是分組(不人為分組時默認整個表就是一個組) group by,下面我們來寫sql語句:

首先在聯表或子連接前可以通過score表分組得到student_id和平均成績:

select student_id,avg(num) as avg_score from score group by student_id having avg(num) >80;

然后在以上虛擬表的基礎上通過student_id拼接student表,取student.sname和avg_score即可

SELECT
    student.sname,
    k.avg_score 
FROM
    student
    INNER JOIN ( SELECT student_id, avg( num ) AS avg_score FROM score GROUP BY student_id HAVING avg( num ) > 80 ) AS k ON k.student_id = student.sid;

 

3、 查詢沒有報李平老師課的學生姓名

需求分析:我們根據表結構得知我們需要用到student,score,course,teacher這4張表,直接得到沒有報李平老師課程的學生比較困難,那么我們就反過來想,哪些是報了李平老師課程的,然后在學生表里剔除掉即可:

首先我們可以先得到李平老師教了哪幾門課,用course和teacher聯表:

select course.cid,course.cname from course inner join teacher on course.teacher_id = teacher.tid where teacher.tname = "李平老師";

根據表結構我們可以知道,course表和score表通過外鍵連接,那么我們就可以把上面得到的虛擬表和score表子查詢,取字段score.student_id即可得到所有選了李平老師課程的學生id,然后根據student_id分組或去重就可以得到不重名的學生id選了李平老師課程的虛擬表:

select score.student_id from score where course_id in (

select course.cid from course inner join teacher on course.teacher_id = teacher.tid where teacher.tname = "李平老師"
) ;

然后將上面得到的虛擬表與student表做子連接的條件得到選了李平老師課程的學生姓名,然后我們not in即可得到需求

select sname from student where sid not  in (

select score.student_id from score where course_id in (

select course.cid from course inner join teacher on course.teacher_id = teacher.tid where teacher.tname = "李平老師"
) 
);

 

 

 

4、 查詢選修物理課程和體育課程的其中一門的學生姓名

需求分析:需要通過課程得到學生姓名,通過表結構我們可以得知,需要用到 student、score、course表,需要得到選了這兩門課程的學生姓名,那我們就可以通過course表先拿到物理課和體育課對應的id,然后把這個id作為score表的查詢條件查出對應的student_id,然后我們可以對student_id進行分組后用having過濾掉group_concat(student_id)大於等於2的部分,即可得到只選修了這兩門課程中其中一門的學生id,然后我們可以拿這個結果去作為student表的子連接條件得到學生姓名,sql語句如下:

SELECT
    student.sname 
FROM
    student 
WHERE
    sid IN (
    SELECT
        student_id 
    FROM
        score 
    WHERE
        course_id IN ( SELECT cid FROM course WHERE cname IN ( "物理", "體育" ) ) 
    GROUP BY
        student_id 
    HAVING
        count( student_id ) = 1 
    );

第二種查詢方法:

SELECT
    k.sname,
    k.course_id 
FROM
    course
    INNER JOIN ( SELECT student.sname, score.course_id FROM student INNER JOIN score ON score.student_id = student.sid ) AS k ON course.cid = k.course_id 
WHERE
    course.cname IN ( "物理", "體育" ) 
GROUP BY
    k.sname 
HAVING
    count( k.sname ) = 1;

 

 

5、 查詢掛科超過兩門(包括兩門)的學生姓名和班級

需求分析:這個需求和第四個需求類似,我們可以先拿到所有掛科的學生id,然后進行分組,篩選出掛科數大於等於2的一部分學生id,然后把取到的id作為student表的查詢條件去取學生姓名即可,sql語句如下:

SELECT
    caption,
    k.sname 
FROM
    class
    INNER JOIN (
    SELECT
        sname,
        class_id 
    FROM
        student 
    WHERE
        sid IN ( SELECT student_id FROM score WHERE num < 60 GROUP BY student_id HAVING count( student_id ) >= 2 ) 
    ) k ON k.class_id = class.cid;

 

6、找出同時選了李平老師所有課的學生班級和姓名

需求分析:需要用到班級和老師,那么5張表都要用到,我們還是套用前面的方法,先通過teacher表找到李平老師的id,通過這個id在course表里找到李平老師的課程表的id,然后拿這個id去score表里找選了李平老師課程的student_id,這時候我們要對student_id進行分組了,篩選出含2個以上的student_id,再通過得到的student_id去student_表里找到對應的姓名和class_id,然后將生成的虛擬表去和class表聯表,取出class.cname和student.sname即是我們想要的數據,sql語句如下:

SELECT
    class.caption,
    n.sname 
FROM
    class
    INNER JOIN (
    SELECT
        class_id,
        sname 
    FROM
        student 
    WHERE
        sid IN (
        SELECT
            student_id 
        FROM
            (
            SELECT
                student_id,
                course_id 
            FROM
                score 
            WHERE
                course_id IN ( SELECT course.cid FROM teacher INNER JOIN course ON course.teacher_id = teacher.tid WHERE teacher.tid = 2 ) 
            ) AS k 
        GROUP BY
            student_id 
        HAVING
            count( student_id ) = 2 
        ) 
    ) AS n ON class.cid = n.class_id ORDER BY n.sname;

 

 

今天的聯表查詢到這里就結束啦!給個贊唄~

 


免責聲明!

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



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