zoukankan      html  css  js  c++  java
  • sql 练习

       今天去面试发现自己的sql很差,多以打算恶补一下.

    建表:

    DROP TABLE IF EXISTS `course`;
    CREATE TABLE `course` (
      `Cno` varchar(10) DEFAULT NULL,
      `Cname` varchar(10) DEFAULT NULL,
      `Tno` varchar(10) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of course
    -- ----------------------------
    INSERT INTO `course` VALUES ('01', '语文', '02');
    INSERT INTO `course` VALUES ('02', '数学', '01');
    INSERT INTO `course` VALUES ('03', '英语', '03');
    
    -- ----------------------------
    -- Table structure for sc
    -- ----------------------------
    DROP TABLE IF EXISTS `sc`;
    CREATE TABLE `sc` (
      `Sno` varchar(10) DEFAULT NULL,
      `Cno` varchar(10) DEFAULT NULL,
      `score` decimal(18,1) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of sc
    -- ----------------------------
    INSERT INTO `sc` VALUES ('01', '01', '80.0');
    INSERT INTO `sc` VALUES ('01', '02', '91.0');
    INSERT INTO `sc` VALUES ('01', '03', '99.0');
    INSERT INTO `sc` VALUES ('02', '01', '70.0');
    INSERT INTO `sc` VALUES ('02', '02', '60.0');
    INSERT INTO `sc` VALUES ('02', '03', '80.0');
    INSERT INTO `sc` VALUES ('03', '01', '81.0');
    INSERT INTO `sc` VALUES ('03', '02', '82.0');
    INSERT INTO `sc` VALUES ('03', '03', '79.0');
    INSERT INTO `sc` VALUES ('04', '01', '50.0');
    INSERT INTO `sc` VALUES ('04', '02', '30.0');
    INSERT INTO `sc` VALUES ('04', '03', '20.0');
    INSERT INTO `sc` VALUES ('05', '01', '76.0');
    INSERT INTO `sc` VALUES ('05', '02', '87.0');
    INSERT INTO `sc` VALUES ('06', '01', '31.0');
    INSERT INTO `sc` VALUES ('06', '03', '34.0');
    INSERT INTO `sc` VALUES ('07', '02', '89.0');
    INSERT INTO `sc` VALUES ('07', '03', '98.0');
    
    -- ----------------------------
    -- Table structure for student
    -- ----------------------------
    DROP TABLE IF EXISTS `student`;
    CREATE TABLE `student` (
      `Sno` varchar(10) DEFAULT NULL,
      `Sname` varchar(10) DEFAULT NULL,
      `Sage` datetime DEFAULT NULL,
      `Ssex` varchar(10) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of student
    -- ----------------------------
    INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01 00:00:00', '');
    INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21 00:00:00', '');
    INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20 00:00:00', '');
    INSERT INTO `student` VALUES ('04', '李云', '1990-08-06 00:00:00', '');
    INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01 00:00:00', '');
    INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01 00:00:00', '');
    INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01 00:00:00', '');
    INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20 00:00:00', '');
    INSERT INTO `student` VALUES ('09', '李云', '1992-10-01 10:34:18', '');
    
    -- ----------------------------
    -- Table structure for teacher
    -- ----------------------------
    DROP TABLE IF EXISTS `teacher`;
    CREATE TABLE `teacher` (
      `Tno` varchar(10) DEFAULT NULL,
      `Tname` varchar(10) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of teacher
    -- ----------------------------
    INSERT INTO `teacher` VALUES ('01', '张三');
    INSERT INTO `teacher` VALUES ('02', '李四');
    INSERT INTO `teacher` VALUES ('03', '王五');
    View Code

    sql:

    -- 1. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
    SELECT
        *
    FROM
        (
            SELECT
                *
            FROM
                sc
            WHERE
                sc.Cno = '01'
        ) sc1
    JOIN (
        SELECT
            *
        FROM
            sc
        WHERE
            sc.Cno = '02'
    ) sc2 ON sc1.sno = sc2.sno
    WHERE
        sc1.score > sc2.score;
    
    --  1.1 查询同时存在" 01 "课程和" 02 "课程的情况
    SELECT
        *
    FROM
        (
            SELECT
                *
            FROM
                sc
            WHERE
                sc.Cno = '01'
        ) sc1
    LEFT JOIN (
        SELECT
            *
        FROM
            sc
        WHERE
            sc.Cno = '02'
    ) sc2 ON sc1.sno = sc2.sno
    WHERE
        sc2.sno IS NOT NULL;
    
    -- 1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
    SELECT
        *
    FROM
        (
            SELECT
                *
            FROM
                sc
            WHERE
                sc.Cno = '01'
        ) sc1
    LEFT JOIN (
        SELECT
            *
        FROM
            sc
        WHERE
            sc.Cno = '02'
    ) sc2 ON sc1.sno = sc2.sno;
    
    -- 查询不存在" 01 "课程但存在" 02 "课程的情况
    SELECT
        *
    FROM
        sc
    WHERE
        sc.Cno = '02'
    AND sc.Sno NOT IN (
        SELECT
            sc.sno
        FROM
            sc
        WHERE
            sc.Cno = '01'
    );
    
    -- 2. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩  
    SELECT
        st.sno,
        st.Sname,
        sc2.score
    FROM
        student st
    JOIN (
        SELECT
            sc.sno,
            AVG(sc.score) AS score
        FROM
            sc
        GROUP BY
            sc.sno
        HAVING
            AVG(sc.score) >= 60
    ) sc2 ON sc2.sno = st.Sno;
    
    -- 3. 查询在 SC 表存在成绩的学生信息 
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno IN (SELECT sno FROM sc GROUP BY sno);
    
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno IN (SELECT DISTINCT sno FROM sc);
    
    SELECT
        st.*
    FROM
        student st
    WHERE
        EXISTS (
            SELECT
                *
            FROM
                sc s
            WHERE
                s.sno = st.sno
        );
    
    -- 4. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为null)  
    SELECT
        A.Sno AS 学生编号,
        A.Sname AS 学生姓名,
        B.`选课数量`,
        B.`总成绩`
    FROM
        student AS A
    LEFT JOIN (
        SELECT
            sc.Sno,
            COUNT(sc.score) AS 选课数量,
            SUM(sc.score) AS 总成绩
        FROM
            sc
        GROUP BY
            sc.Sno
    ) AS B ON A.Sno = B.Sno;
    
    -- 4.1 查有成绩的学生信息
    SELECT
        *
    FROM
        student S
    JOIN (
        SELECT
            sc.Sno
        FROM
            sc
        GROUP BY
            sc.Sno
    ) A ON S.Sno = A.Sno;
    
    SELECT
        *
    FROM
        student s
    WHERE
        EXISTS (
            SELECT
                *
            FROM
                (
                    SELECT
                        sc.Sno
                    FROM
                        sc
                    GROUP BY
                        sc.Sno
                ) A
            WHERE
                s.sno = A.sno
        );
    
    -- 5.查询「李」姓老师的数量   
    SELECT
        count(*)
    FROM
        teacher
    WHERE
        Tname LIKE '李%';
    
    -- 6.查询学过「张三」老师授课的同学的信息
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno IN (
            SELECT
                Sno
            FROM
                sc
            WHERE
                sc.Cno IN (
                    SELECT
                        Cno
                    FROM
                        course
                    WHERE
                        course.Tno IN (
                            SELECT
                                Tno
                            FROM
                                teacher
                            WHERE
                                Tname = '张三'
                        )
                )
        ) -- 7.查询没有学全所有课程的同学的信息
        SELECT
            student.*
        FROM
            student
        LEFT JOIN (SELECT sno FROM sc GROUP BY sno) s1 ON s1.sno = student.Sno
        WHERE
            s1.sno IS NULL -- 查出没学的
        UNION
            SELECT
                student.*
            FROM
                student
            JOIN (
                SELECT
                    sno
                FROM
                    sc
                GROUP BY
                    sno
                HAVING
                    COUNT(1) < (SELECT COUNT(1) FROM course)
            ) s2 ON s2.sno = student.Sno;
    
    -- 查出没学全的
    -- 8. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno IN (
            SELECT DISTINCT
                sc.Sno
            FROM
                sc
            WHERE
                sc.Cno IN (
                    SELECT
                        cno
                    FROM
                        sc
                    WHERE
                        sc.Sno = '01'
                )
        );
    
    -- 9. 查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
    SELECT
        *
    FROM
        Student
    WHERE
        Sno IN (
            SELECT
                Sno
            FROM
                SC
            WHERE
                Cno IN (
                    SELECT DISTINCT
                        Cno
                    FROM
                        SC
                    WHERE
                        Sno = '01'
                )
            AND Sno <> '01'
            GROUP BY
                Sno
            HAVING
                COUNT(Cno) >= 3
        );
    
    -- 10. 查询没学过「张三」老师讲授的任一门课程的学生姓名 
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno NOT IN (
            SELECT
                sno
            FROM
                sc
            WHERE
                sc.Cno IN (
                    SELECT
                        course.cno
                    FROM
                        course
                    WHERE
                        course.Tno = (
                            SELECT
                                tno
                            FROM
                                teacher
                            WHERE
                                teacher.Tname = '张三'
                        )
                )
        );
    
    -- 11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
    SELECT
        student.*, s2.avg
    FROM
        student
    JOIN (
        SELECT
            sc.Sno,
            AVG(sc.score) AS avg
        FROM
            sc
        WHERE
            sc.score < 60
        GROUP BY
            sc.Sno
        HAVING
            COUNT(1) >= 2
    ) s2 ON s2.Sno = student.Sno -- 12.检索" 01 "课程分数小于 60 ,按分数降序排列的学生信息   
    SELECT
        *
    FROM
        sc
    WHERE
        sc.Cno = '01'
    AND sc.score < 60
    ORDER BY
        sc.score DESC;
    
    -- 13. (静态写法)按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
    SELECT
        info.sno AS 学号,
        info.Sname AS 学生姓名,
        SUM(
            CASE info.Cname
            WHEN '语文' THEN
                info.score
            END
        ) AS 语文,
        SUM(
            CASE info.Cname
            WHEN '数学' THEN
                info.score
            END
        ) AS 数学,
        SUM(
            CASE info.Cname
            WHEN '英语' THEN
                info.score
            END
        ) AS 英语,
        SUM(info.score)/3 AS 平均分
    FROM
        (
            SELECT
                student.sno,
                student.Sname,
                course.Cname,
                sc.score
            FROM
                sc
            JOIN student ON sc.Sno = student.Sno
            JOIN course ON sc.Cno = course.Cno
        ) AS info
    GROUP BY
        info.sno
    
    
    -- 19. 查询每门课程被选修的学生数  
    
    select  sc.Cno ,count(1) from  sc group by  sc.Cno ;
    
    
    -- 20. 查询出只选修两门课程的学生学号和姓名   
    
    
    SELECT
        *
    FROM
        student
    WHERE
        EXISTS (
            SELECT
                *
            FROM
                (
                    SELECT
                        sc.Sno
                    FROM
                        sc
                    GROUP BY
                        sc.Sno
                    HAVING
                        COUNT(1) = 2
                ) a
            WHERE
                a.Sno = student.Sno
        );
    
    
    
    SELECT
        *
    FROM
        student
    WHERE
        student.Sno IN (
            SELECT
                sc.Sno
            FROM
                sc
            GROUP BY
                sc.Sno
            HAVING
                COUNT(1) = 2
        );
    
    -- 21. 查询男生、女生人数  
      
    select Ssex,COUNT(Ssex)人数 from Student group by Ssex    ;
    
    -- 22. 查询名字中含有「风」字的学生信息 
    select  * from  student where student.Sname like  '%风%';
    
    -- 23. 查询同名同性学生名单,并统计同名人数 
    
    SELECT
        Sname,
        Ssex,
        COUNT(*) 同名人数
    FROM
        Student
    GROUP BY
        Sname,
        Ssex
    HAVING
        COUNT(*) > 1;
    
    -- 24.查询 1990 年出生的学生名单 
    select  * from  student where year(student.Sage)='1990';
    
    -- 25. 查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列  
    
    select  sc.Cno,AVG(sc.score) as score from  sc  GROUP BY sc.Cno ORDER BY score desc ,cno asc;
    
    
    -- 26. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
    
    select  student.sno,student.Sname,a.scoreavg from  student  join(
    select  sc.Sno,AVG(sc.score) as scoreavg  from  sc group  by  sc.Sno HAVING AVG(sc.score)>=85
    )a on  a.Sno=student.Sno;
    
    
    -- 27. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
    SELECT
        student.Sno,
        student.Sname,
        course.Cname,
        sc.score
    FROM
        sc
    LEFT JOIN student ON student.Sno = sc.sno
    LEFT JOIN course  ON course.Cno=sc.Cno
    WHERE
        sc.score < 60
    AND EXISTS (
        SELECT
            *
        FROM
            (
                SELECT
                    *
                FROM
                    course
                WHERE
                    course.Cname = '数学'
            ) a
        WHERE
            a.cno = sc.Cno
    );
    
    
    -- 28. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
    
    
    SELECT
        student.sno,
        student.Sname,
        course.Cname,
        sc.score
    FROM
        student
    LEFT JOIN sc ON sc.Sno = student.Sno
    LEFT JOIN course ON course.Cno = sc.Cno;
    
    
    -- 29. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
    select  * from  sc where EXISTS (select  * from  (select  sno from  sc  where  sc.score>=80 GROUP BY sc.Sno HAVING COUNT(1)>=(select  count(1) from  course)) a where a.sno= sc.sno );
    
    
    -- 30. 查询不及格的课程
    select course.Cname  from  sc   join course  on  course.Cno=sc.Cno   where sc.score<60 GROUP BY course.Cname;
    
    
    -- 31. 查询课程编号为01且课程成绩在80分以上的学生的学号和姓名
    
    
    SELECT
        student.Sno,
        student.Sname,
        a.score
    FROM
        student
    JOIN (
        SELECT
            *
        FROM
            sc
        WHERE
            sc.Cno = '01'
        AND sc.score >= 80
    ) a ON a.sno = student.sno
    
    
    -- 32. 求每门课程的学生人数   
    select  sc.cno as 课程编号 ,COUNT(1)  as 人数 from  sc   GROUP BY sc.Cno
    
    --  33.选修张三老师的课程的学生中,成绩最高
    SELECT
        student.Sname, sc.score
    FROM
        sc
    JOIN student ON student.sno = sc.Sno
    WHERE
        sc.score = (
            SELECT
                MAX(sc.score)
            FROM
                sc
            WHERE
                sc.Cno IN (
                    SELECT
                        cno
                    FROM
                        course
                    WHERE
                        course.Tno = (
                            SELECT
                                tno
                            FROM
                                teacher
                            WHERE
                                teacher.Tname = '张三'
                        )
                )
        );
    
    
    -- 37.统计每门课程的学生选修人数(超过5人的课程才统计)。  
    -- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 
    select  sc.cno,COUNT(1) as num from  sc group  by  sc.Cno  HAVING COUNT(1)>5 order  by  num desc ,sc.cno ;
    
    -- 38. 检索至少选修两门课程的学生学号 
    select sc.Sno,COUNT(1) from  sc group  by  sc.Sno HAVING COUNT(1)>2;
    
    
    -- 39. 查询选修了全部课程的学生信息
    select  sc.Sno,COUNT(1) from  sc  group  by  sc.Sno HAVING COUNT(1)=(select  COUNT(1) from  course);
    
    
    -- 40. 查询各学生的年龄,只按年份来算 
    select  student.sno,student.Sname,(YEAR(SYSDATE())-YEAR(student.Sage)) as age from  student
  • 相关阅读:
    在Java当中如何优雅地处理临时文件
    lombok插件不建议使用的原因
    linux系统下修改tomcat的端口号时,需要修改的地方
    linux系统下报错为:直接在tomcat的bin目录下生成一个错误文件。
    Linux下修改tomcat端口号
    python实现断点续传下载文件
    Python中下划线---完全解读
    linux  指令 备注
    Linux下高并发socket最大连接数所受的各种限制
    python和pywin32实现窗口查找、遍历和点击
  • 原文地址:https://www.cnblogs.com/songfahzun/p/8718301.html
Copyright © 2011-2022 走看看