1. 程式人生 > >數據庫---多表查詢練習

數據庫---多表查詢練習

女生 tinc utf8 microsoft CA file 中學 oca navicat

多表查詢練習

導出現有數據庫數據:

  • mysqldump -u用戶名 -p密碼 數據庫名稱 > 導出文件路徑 # 結構+數據
  • mysqldump -u用戶名 -p密碼 -d 數據庫名稱 > 導出文件路徑 # 結構

導入現有數據庫數據:

  • mysql -uroot -p密碼 數據庫名稱 < 文件路徑

1.準備數據:init.sql文件內容:

技術分享圖片
/*
     數據導入:
     Navicat Premium Data Transfer

     Source Server         : localhost
     Source Server Type    : MySQL
     Source Server Version : 50624
     Source Host           : localhost
     Source Database       : sqlexam

     Target Server Type    : MySQL
     Target Server Version : 50624
     File Encoding         : utf-8

     Date: 10/21/2016 06:46:46 AM
    
*/ SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for `class` -- ---------------------------- DROP TABLE IF EXISTS `class`; CREATE TABLE `class` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `caption` varchar(32) NOT NULL
, PRIMARY KEY (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of `class` -- ---------------------------- BEGIN; INSERT INTO `class` VALUES (‘1‘, ‘三年二班‘), (‘2‘, ‘三年三班‘), (‘3‘, ‘一年二班‘), (‘4‘, ‘二年九班‘); COMMIT;
-- ---------------------------- -- Table structure for `course` -- ---------------------------- DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `cname` varchar(32) NOT NULL, `teacher_id` int(11) NOT NULL, PRIMARY KEY (`cid`), KEY `fk_course_teacher` (`teacher_id`), CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of `course` -- ---------------------------- BEGIN; INSERT INTO `course` VALUES (‘1‘, ‘生物‘, ‘1‘), (‘2‘, ‘物理‘, ‘2‘), (‘3‘, ‘體育‘, ‘3‘), (‘4‘, ‘美術‘, ‘2‘); COMMIT; -- ---------------------------- -- Table structure for `score` -- ---------------------------- DROP TABLE IF EXISTS `score`; CREATE TABLE `score` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `student_id` int(11) NOT NULL, `course_id` int(11) NOT NULL, `num` int(11) NOT NULL, PRIMARY KEY (`sid`), KEY `fk_score_student` (`student_id`), KEY `fk_score_course` (`course_id`), CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`), CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of `score` -- ---------------------------- BEGIN; INSERT INTO `score` VALUES (‘1‘, ‘1‘, ‘1‘, ‘10‘), (‘2‘, ‘1‘, ‘2‘, ‘9‘), (‘5‘, ‘1‘, ‘4‘, ‘66‘), (‘6‘, ‘2‘, ‘1‘, ‘8‘), (‘8‘, ‘2‘, ‘3‘, ‘68‘), (‘9‘, ‘2‘, ‘4‘, ‘99‘), (‘10‘, ‘3‘, ‘1‘, ‘77‘), (‘11‘, ‘3‘, ‘2‘, ‘66‘), (‘12‘, ‘3‘, ‘3‘, ‘87‘), (‘13‘, ‘3‘, ‘4‘, ‘99‘), (‘14‘, ‘4‘, ‘1‘, ‘79‘), (‘15‘, ‘4‘, ‘2‘, ‘11‘), (‘16‘, ‘4‘, ‘3‘, ‘67‘), (‘17‘, ‘4‘, ‘4‘, ‘100‘), (‘18‘, ‘5‘, ‘1‘, ‘79‘), (‘19‘, ‘5‘, ‘2‘, ‘11‘), (‘20‘, ‘5‘, ‘3‘, ‘67‘), (‘21‘, ‘5‘, ‘4‘, ‘100‘), (‘22‘, ‘6‘, ‘1‘, ‘9‘), (‘23‘, ‘6‘, ‘2‘, ‘100‘), (‘24‘, ‘6‘, ‘3‘, ‘67‘), (‘25‘, ‘6‘, ‘4‘, ‘100‘), (‘26‘, ‘7‘, ‘1‘, ‘9‘), (‘27‘, ‘7‘, ‘2‘, ‘100‘), (‘28‘, ‘7‘, ‘3‘, ‘67‘), (‘29‘, ‘7‘, ‘4‘, ‘88‘), (‘30‘, ‘8‘, ‘1‘, ‘9‘), (‘31‘, ‘8‘, ‘2‘, ‘100‘), (‘32‘, ‘8‘, ‘3‘, ‘67‘), (‘33‘, ‘8‘, ‘4‘, ‘88‘), (‘34‘, ‘9‘, ‘1‘, ‘91‘), (‘35‘, ‘9‘, ‘2‘, ‘88‘), (‘36‘, ‘9‘, ‘3‘, ‘67‘), (‘37‘, ‘9‘, ‘4‘, ‘22‘), (‘38‘, ‘10‘, ‘1‘, ‘90‘), (‘39‘, ‘10‘, ‘2‘, ‘77‘), (‘40‘, ‘10‘, ‘3‘, ‘43‘), (‘41‘, ‘10‘, ‘4‘, ‘87‘), (‘42‘, ‘11‘, ‘1‘, ‘90‘), (‘43‘, ‘11‘, ‘2‘, ‘77‘), (‘44‘, ‘11‘, ‘3‘, ‘43‘), (‘45‘, ‘11‘, ‘4‘, ‘87‘), (‘46‘, ‘12‘, ‘1‘, ‘90‘), (‘47‘, ‘12‘, ‘2‘, ‘77‘), (‘48‘, ‘12‘, ‘3‘, ‘43‘), (‘49‘, ‘12‘, ‘4‘, ‘87‘), (‘52‘, ‘13‘, ‘3‘, ‘87‘); COMMIT; -- ---------------------------- -- Table structure for `student` -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `gender` char(1) NOT NULL, `class_id` int(11) NOT NULL, `sname` varchar(32) NOT NULL, PRIMARY KEY (`sid`), KEY `fk_class` (`class_id`), CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of `student` -- ---------------------------- BEGIN; INSERT INTO `student` VALUES (‘1‘, ‘男‘, ‘1‘, ‘理解‘), (‘2‘, ‘女‘, ‘1‘, ‘鋼蛋‘), (‘3‘, ‘男‘, ‘1‘, ‘張三‘), (‘4‘, ‘男‘, ‘1‘, ‘張一‘), (‘5‘, ‘女‘, ‘1‘, ‘張二‘), (‘6‘, ‘男‘, ‘1‘, ‘張四‘), (‘7‘, ‘女‘, ‘2‘, ‘鐵錘‘), (‘8‘, ‘男‘, ‘2‘, ‘李三‘), (‘9‘, ‘男‘, ‘2‘, ‘李一‘), (‘10‘, ‘女‘, ‘2‘, ‘李二‘), (‘11‘, ‘男‘, ‘2‘, ‘李四‘), (‘12‘, ‘女‘, ‘3‘, ‘如花‘), (‘13‘, ‘男‘, ‘3‘, ‘劉三‘), (‘14‘, ‘男‘, ‘3‘, ‘劉一‘), (‘15‘, ‘女‘, ‘3‘, ‘劉二‘), (‘16‘, ‘男‘, ‘3‘, ‘劉四‘); COMMIT; -- ---------------------------- -- Table structure for `teacher` -- ---------------------------- DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `tid` int(11) NOT NULL AUTO_INCREMENT, `tname` varchar(32) NOT NULL, PRIMARY KEY (`tid`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of `teacher` -- ---------------------------- BEGIN; INSERT INTO `teacher` VALUES (‘1‘, ‘張磊老師‘), (‘2‘, ‘李平老師‘), (‘3‘, ‘劉海燕老師‘), (‘4‘, ‘朱雲海老師‘), (‘5‘, ‘李傑老師‘); COMMIT; SET FOREIGN_KEY_CHECKS = 1; 準備數據
準備數據

2.從init.sql文件中導入數據

  • #準備表、記錄
  • mysql> create database db1;
  • mysql> use db1;
  • mysql> source /root/init.sql

3.題目

1、查詢所有的課程的名稱以及對應的任課老師姓名
2、查詢學生表中男女生各有多少人
3、查詢物理成績等於100的學生的姓名
4、查詢平均成績大於八十分的同學的姓名和平均成績
5、查詢所有學生的學號,姓名,選課數,總成績
6、查詢姓李老師的個數
7、查詢沒有報李平老師課的學生姓名
8、查詢物理課程比生物課程高的學生的學號
9、查詢沒有同時選修物理課程和體育課程的學生姓名
10、查詢掛科超過兩門(包括兩門)的學生姓名和班級
11、查詢選修了所有課程的學生姓名
12、查詢李平老師教的課程的所有成績記錄
13、查詢全部學生都選修了的課程號和課程名
14、查詢每門課程被選修的次數
15、查詢之選修了一門課程的學生姓名和學號
16、查詢所有學生考出的成績並按從高到低排序(成績去重)
17、查詢平均成績大於85的學生姓名和平均成績
18、查詢生物成績不及格的學生姓名和對應生物分數
19、查詢在所有選修了李平老師課程的學生中,這些課程(李平老師的課程,不是所有課程)平均成績最高的學生姓名
20、查詢每門課程成績最好的前兩名學生姓名
21、查詢不同課程但成績相同的學號,課程號,成績
22、查詢沒學過“葉平”老師課程的學生姓名以及選修的課程名稱;
23、查詢所有選修了學號為1的同學選修過的一門或者多門課程的同學學號和姓名;
24、任課最多的老師中學生單科成績最高的學生姓名

4.答案

#1、查詢所有的課程的名稱以及對應的任課老師姓名
        select
            course.cname,
            teacher.tname
        from
            course
        inner join teacher on course.teacher_id = teacher.tid;

    #2、查詢學生表中男女生各有多少人
        select
            gender,
            count(1)   # count(sid)
        from
            student
        group by
            gender;

    #3、查詢物理成績等於100的學生的姓名
        select
            sname
        from
            student
        where
            sid in(
                select
                    t1.student_id
                from
                    score t1
                inner join(
                    select
                        cid
                    from
                        course
                    where
                        cname = 物理
                ) t2 on t1.course_id = t2.cid
                where
                    t1.num = 100
            );

    #4、查詢平均成績大於八十分的同學的姓名和平均成績
        select
            t1.sname,
            t2.avg_num
        from
            student as t1
        inner join(
            select
                student_id,
                avg(num) as avg_num
            from
                score
            group by
                student_id
            having
                avg(num) > 80
        ) as t2 on t1.sid = t2.student_id;

    #5、查詢所有學生的學號,姓名,選課數,總成績(註意:對於那些沒有選修任何課程的學生也算在內)
        select
            t1.sid,
            t1.sname,
            t2.count_course,
            t2.sum_num
        from
            student as t1
        left join(
            select
                student_id,
                count(course_id) as count_course,
                sum(num) as sum_num
            from
                score
            group by
                student_id
        ) as t2 on t1.sid = t2.student_id;

    #6、 查詢姓李老師的個數
        select
            count(tid)
        from
            teacher
        where
            tname like 李%;

    #7、 查詢沒有報李平老師課的學生姓名
        select
            sname
        from
            student
        where
            sid not in(
                select distinct
                    student_id
                from
                    score
                where
                    course_id in (
                        select
                            cid
                        from
                            course
                        inner join teacher on course.teacher_id = teacher.tid
                        where teacher.tname = 李平老師
                    )
            );

    #8、 查詢物理課程比生物課程高的學生的學號(分別得到物理成績表與生物成績表,然後連表即可)
        select
            t1.student_id,
            t1.num,
            t2.num
        from
            (
                select
                    student_id,
                    num
                from
                    score
                where
                    course_id = (
                        select
                            cid
                        from
                            course
                        where
                            cname = 物理
                    )
            ) as t1
        inner join (
            select
                student_id,
                num
            from
                score
            where
                course_id = (
                    select
                        cid
                    from
                        course
                    where
                        cname = 生物
                )
        ) as t2 on t1.student_id = t2.student_id
        where
            t1.num > t2.num;

    #9、 查詢沒有同時選修物理課程和體育課程的學生姓名
    # 包含了物理,體育都沒選得
    select
        sname
    from
        student
    where
        sid not in (
            select
                t1.student_id
            from
                (
                    select
                        student_id,
                        course_id
                    from
                        score
                    where
                        course_id in (
                            select
                                cid
                            from
                                course
                            where
                                cname in (
                                    物理,
                                    體育
                                )
                        )
                ) as t1
            group by
                t1.student_id
            having
                count(t1.student_id) = 2
        );
        # 只選修了一門
        select
            sname
        from
            student
        where
            sid in (
                select
                    t1.student_id
                from
                    (
                        select
                            student_id,
                            course_id
                        from
                            score
                        where
                            course_id in (
                                select
                                    cid
                                from
                                    course
                                where
                                    cname in (
                                        物理,
                                        體育
                                    )
                            )
                    ) as t1
                group by
                    t1.student_id
                having
                    count(t1.student_id) = 1
            );
            # 另一種方法:
            SELECT
                student.sname
            FROM
                student
            WHERE
                sid IN (
                    SELECT
                        student_id
                    FROM
                        score
                    WHERE
                        course_id IN (
                            SELECT
                                cid
                            FROM
                                course
                            WHERE
                                cname = 物理
                            OR cname = 體育
                        )
                    GROUP BY
                        student_id
                    HAVING
                        COUNT(course_id) = 1
                );

    #10、查詢掛科超過兩門(包括兩門)的學生姓名和班級
        select
            t1.caption,
            t2.sname
        from
            class as t1
        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(sid) >= 2
                )
        ) as t2 on t1.cid = t2.class_id;
        #另一種方法:
        SELECT
            student.sname,
            class.caption
        FROM
            student
        INNER JOIN (
            SELECT
                student_id
            FROM
                score
            WHERE
                num < 60
            GROUP BY
                student_id
            HAVING
                count(course_id) >= 2
        ) AS t1
        INNER JOIN class ON student.sid = t1.student_id
        AND student.class_id = class.cid;

    #11、查詢選修了所有課程的學生姓名
        select
            sname
        from
            student
        where
            sid in (
                select
                    student_id
                from
                    score
                group by
                    student_id
                having
                    count(sid) = (
                        select
                            count(cid)
                        from
                            course
                    )
            );

    #12、查詢李平老師教的課程的所有成績記錄
        select
            *
        from
            score
        where
            course_id in (
                select
                    cid
                from
                    course
                inner join teacher on course.teacher_id = teacher.tid
                where
                    teacher.tname = 李平老師
            );

    #13、查詢全部學生都選修了的課程號和課程名(取所有學生數,然後基於score表的課程分組,找出count(student_id)等於學生數即可)
        select
            cid,
            cname
        from
            course
        where
            cid in (
                select
                    course_id
                from
                    score
                group by
                    course_id
                having
                    count(sid) = (select count(sid) from student)
            );

    #14、查詢每門課程被選修的次數
        select
            course_id,
            count(sid)
        from
            score
        right join course on score.course_id = course.cid
        group by
            course_id
        order by
            course_id;

        SELECT
            course_id,
            COUNT(student_id)
        FROM
            score
        GROUP BY
            course_id;

    #15、查詢之選修了一門課程的學生姓名和學號
        select
            sid,
            sname
        from
            student
        where
            sid in (
                select
                    student_id
                from
                    score
                group by
                    student_id
                having
                    count(sid) = 1
            );

    #16、查詢所有學生考出的成績並按從高到低排序(成績去重)
        select distinct
            num
        from
            score
        order by
            num desc;

    #17、查詢平均成績大於85的學生姓名和平均成績
        select
            student.sname,
            t1.avg_num
        from
            student
        inner join (
            select
                student_id,
                avg(num) as avg_num
            from
                score
            group by
                student_id
            having
                avg(num) > 85
        ) as t1 on student.sid = t1.student_id;

    #18、查詢生物成績不及格的學生姓名和對應生物分數
        select
            sname,
            t1.num
        from
            student
        inner join (
            select
                student_id,
                num
            from
                score
            inner join course on score.course_id = course.cid
            where course.cname = 生物
                and score.num < 60
        ) as t1 on student.sid = t1.student_id;
        # 另一種方法:
        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
            course.cname = 生物
            and score.num < 60;

    #19、查詢在所有選修了李平老師課程的學生中,這些課程(李平老師的課程,不是所有課程)平均成績最高的學生姓名
        select
            sname,
            t1.avg_num
        from
            student
        inner join (
            select
                student_id,
                avg(num) as avg_num
            from
                score
            where
                course_id in (
                    select
                        cid
                    from
                        course
                    inner join teacher on course.teacher_id = teacher.tid
                    where teacher.tname = 李平老師
                )
            group by
                student_id
            order by
                avg_num desc
            limit 1
        ) as t1 on student.sid = t1.student_id;

    #20、查詢每門課程成績最好的前兩名學生姓名
        select
            student.sname,
            num_table.course_id,
            num_table.first_num,
            num_table.second_num
        from
            student
        inner join (
            select
                score.sid,
                score.course_id as course_id,
                score.student_id,
                t.first_num as first_num,
                t.second_num as 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 s3 where s3.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
        ) as num_table on student.sid = num_table.student_id;

    #21、查詢不同課程但成績相同的學號,課程號,成績
        select distinct
            s1.student_id,
            s1.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;

        select distinct
            *
        from
            score as s1,
            score as s2
        where
            s1.num = s2.num

    #22、查詢沒學過李平老師課程的學生姓名以及選修的課程名稱;
        select
            student.sname,
            course.cname
        from
            (
                select
                    student_id,
                    course_id
                from
                    score
                where
                    course_id not in (
                        select
                            cid
                        from
                            course
                        inner join teacher on course.teacher_id = teacher.tid
                        where teacher.tname = 李平老師
                    )
            ) as t1
        inner join course on t1.course_id = course.cid
        inner join student on t1.student_id = student.sid
        order by student.sname;

    #23、查詢所有選修了學號為1的同學選修過的一門或者多門課程的同學學號和姓名;
         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
        # 另一種方法:
        select
            sid,
            sname
        from
            student
        where
            sid in (
                select
                    student_id
                from
                    score
                where
                    course_id in (
                        select
                            course_id
                        from
                            score
                        where
                            student_id = 1
                    )
            )
            and sid !=1

    #24、任課最多的老師中學生單科成績最高的學生姓名
        select
            sid,
            sname
        from
            student
        where
            sid in (
                select distinct
                    t1.id_students
                from
                    (
                        select
                            group_concat(student_id) as id_students,
                            course_id,
                            max(num)
                        from
                            score
                        where
                            course_id in (
                                select
                                    cid
                                from
                                    course
                                where
                                    teacher_id in (
                                        select
                                            teacher_id
                                        from
                                            course
                                        group by
                                            teacher_id
                                        having
                                            count(cid) = (
                                                select
                                                    count(cid)
                                                from
                                                    course
                                                group by
                                                    teacher_id
                                                order by
                                                    count(cid) desc
                                                limit 1
                                            )
                                    )
                            )
                        group by
                            course_id
                    ) as t1
            );

數據庫---多表查詢練習