zoukankan      html  css  js  c++  java
  • SQL面试50题

     1.查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号(重点)
    SELECT a.s_id,a.s_score FROM
    (SELECT * FROM score WHERE c_id='01') as a
    INNER JOIN
    (SELECT * FROM score WHERE c_id='02') as b
    on a.s_id=b.s_id
    WHERE a.s_score>b.s_score;
    View Code




    15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩(重点)
    SELECT a.s_id,a.s_name,avg(s_score) FROM student as a
    INNER JOIN score as b
    ON a.s_id=b.s_id
    
    WHERE a.s_id IN(
    SELECT s_id FROM score
    WHERE s_score<60 GROUP BY s_id HAVING COUNT(DISTINCT c_id)>=2
      )
    GROUP BY a.s_id,s_name
    View Code
    16、检索"01"课程分数小于60,按分数降序排列的学生信息
    # 方法一:个人
    SELECT * FROM student
    INNER JOIN
    (SELECT s_id,s_score FROM score WHERE c_id=01 AND s_score<60) as t
    on student.s_id=t.s_id
    ORDER BY s_score DESC;
    
    # 方法二:个人
    SELECT * FROM student
    INNER JOIN score ON student.s_id=score.s_id
    
    WHERE s_score<60 AND c_id=01
    ORDER BY s_score DESC;
    
    # 方法三:
    SELECT * FROM student as t
    INNER JOIN score as s on t.s_id=s.s_id
    WHERE s.c_id=01 AND s.s_score<60
    ORDER BY s.s_score DESC ;
    View Code

     17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩(重重点与35一样)

    SELECT s_id "学号",
    max(CASE WHEN c_id=01 THEN s_score ELSE NULL END ) "语文",
    max(CASE WHEN c_id=02 THEN s_score ELSE NULL END ) "数学",
    max(CASE WHEN c_id=03 THEN s_score ELSE NULL END ) "英语",
    avg(s_score) "平均成绩" FROM score
    GROUP BY s_id
    ORDER BY avg(s_score) DESC
    View Code

    18.查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

    SELECT s.c_id "课程ID",c.c_name "课程名字",
    max(s.s_score) "最高分",
    min(s.s_score)"最低分",
    avg(s.s_score)"平均分",
    sum(CASE WHEN s.s_score>=60 THEN 1 ELSE 0 END )/count(s_id) "及格",
    sum(CASE WHEN s.s_score>=70 AND s.s_score<80 THEN 1 ELSE 0 END )/count(s_id) "中等",
    sum(CASE WHEN s.s_score>=80 AND s.s_score<90 THEN 1 ELSE 0 END )/count(s_id)"优良",
    sum(CASE WHEN s.s_score>=90 THEN 1 ELSE 0 END )/count(s_id) "优秀"
    FROM course AS c
    INNER JOIN
    score as s ON c.c_id=s.c_id
    GROUP BY c.c_id
    View Code
    SELECT c_id,
           avg(CASE WHEN s_score >= 0 AND s_score < 60 THEN 1.0 ELSE 0.0 END)   "及格率",
           avg(CASE WHEN s_score >= 60 AND s_score < 70 THEN 1.0 ELSE 0.0 END)  "中等率",
           avg(CASE WHEN s_score >= 70 AND s_score < 85 THEN 1.0 ELSE 0.0 END)  "良好率",
           avg(CASE WHEN s_score >= 85 AND s_score < 100 THEN 1.0 ELSE 0.0 END) "优秀率"
    FROM score
    GROUP BY c_id;
    View Code

    19、按各科成绩进行排序,并显示排名(重点row_number)

    窗口函数可以进行排序,生成序列号等一般的聚合函数无法实现的高级操作。

    窗口函数大体可以分为以下两种:

    1.能够作为窗口函数的聚合函数(sum,avg,count,max,min)

    2.rank,dense_rank,row_number等专用窗口函数。

    语法的基本使用方法:使用rank函数

    rank函数是用来计算记录排序的函数
    https://blog.csdn.net/qq_41805514/article/details/81772182

    专用函数的种类:1.rank函数:计算排序时,如果存在相同位次的记录,则会跳过之后的位次。

                                 2.dense_rank函数:同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次。

                                 3.row_number函数:赋予唯一的连续位次。

      23、使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称(重点和18题类似)

    SELECT c.c_id "课程ID",c_name "课程名字",
    sum(CASE WHEN s_score<=100 and s_score>85 THEN 1 ELSE 0 END ) AS "[100,85]",
    sum(CASE WHEN s_score<=85 and s_score>70 THEN 1 ELSE 0 END ) "[85,70]",
    sum(CASE WHEN s_score<=70 and s_score>60 THEN 1 ELSE 0 END )"[70,60]",
    sum(CASE WHEN s_score<=60 THEN 1 ELSE 0 END )"<60"
    
    FROM score as s
    INNER JOIN course as c on s.c_id=c.c_id
    GROUP BY c.c_id,c.c_name;
    View Code
    SELECT c.c_id "课程ID",c_name "课程名字",
    count(CASE WHEN s_score<=100 and s_score>85 THEN 1 ELSE NULL END ) AS "[100,85]",
    count(CASE WHEN s_score<=85 and s_score>70 THEN 1 ELSE NULL END ) "[85,70]",
    count(CASE WHEN s_score<=70 and s_score>60 THEN 1 ELSE NULL END )"[70,60]",
    count(CASE WHEN s_score<=60 THEN 1 ELSE NULL END )"<60"
    
    FROM score as s
    INNER JOIN course as c on s.c_id=c.c_id
    GROUP BY c.c_id,c.c_name;
    View Code
    24、查询学生平均成绩及其名次(同19题,重点)
    SELECT s_id,avg(s_score),
           rank() OVER (ORDER BY avg(s_score)) as ranking FROM score
    group by s_id
    
    
    # 不可加partition by,需使用group by
    View Code
    25、查询各科成绩前三名的记录(不考虑成绩并列情况)(重点 与22题类似)
    26、查询每门课程被选修的学生数(不重点)
    26、查询每门课程被选修的学生数(不重点)
    SELECT c_name,COUNT(c.c_id)
    FROM score as s
    INNER JOIN
    course as c on s.c_id=c.c_id
    GROUP BY c_name;
    
    # 注:一般需要将select后的字段放在group by后面
    
    SELECT c.c_id,c.c_name,count(DISTINCT s.s_id) AS "数量"
    FROM score as s
    INNER JOIN
    course as c on s.c_id=c.c_id
    GROUP BY c.c_id,c.c_name;
    View Code

    27、 查询出只有两门课程的全部学生的学号和姓名(不重点)
    # 方法一:
    SELECT s.s_id,s.s_name
    FROM student AS s
    INNER JOIN
      score as sc on s.s_id=sc.s_id
    GROUP BY s.s_id HAVING count(DISTINCT c_id)=2;
    
    # 错误
    SELECT s.s_name,s.s_id
    FROM student AS s
    INNER JOIN
      score as sc on s.s_id=sc.s_id
    WHERE count(DISTINCT c_id)=2;
    
    # 方法二:
    SELECT s_id,s_name FROM student
    WHERE s_id in(SELECT s_id FROM score GROUP BY s_id
      HAVING count(DISTINCT c_id)=2);
    View Code
    28、查询男生、女生人数(不重点)
    
    
    # 方法一:
    SELECT s_sex,count(s_sex) FROM student
    GROUP BY s_sex;
    # 方法二:
    SELECT
    sum(CASE WHEN s_sex='' THEN 1 ELSE 0 END ) "男生人数",
    sum(CASE WHEN s_sex='' THEN 1 ELSE 0 END ) "女生人数"
    FROM student
    # 方法三:
    SELECT
    count(CASE WHEN s_sex='' THEN 1 ELSE NULL END ) "男生人数",
    count(CASE WHEN s_sex='' THEN 1 ELSE NULL END ) "女生人数"
    FROM student
    
    # 注:null对count来说是不计算个数的,所以后面不能写0,只能用null
    View Code
    35、查询所有学生的课程及分数情况(重点)
    # 不对
    SELECT s.s_id,s.s_name,c.c_name,sc.s_score
    FROM student as s
    INNER JOIN score as sc
    ON s.s_id=sc.s_id
    INNER JOIN course as c
    ON c.c_id=sc.c_id
    GROUP BY s.s_id,s.s_name
    
    # 正确做法:(行转列)
    SELECT s.s_id,s.s_name,
    max(CASE WHEN c.c_name="语文" THEN s_score ELSE NULL END ) AS "语文",
    max(CASE WHEN c.c_name="数学" THEN s_score ELSE NULL END ) AS "数学",
    max(CASE WHEN c.c_name="英语" THEN s_score ELSE NULL END ) AS "英语"
    FROM student as s
    LEFT JOIN score as sc
    ON s.s_id=sc.s_id
    LEFT JOIN course as c
    ON c.c_id=sc.c_id
    GROUP BY s.s_id,s.s_name
    View Code
    
    

     36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数(重点)

    # 错误处理方法:
    SELECT s.s_name,c.c_name,sc.s_score
    FROM student as s
    INNER JOIN score as sc on s.s_id=sc.s_id
    INNER JOIN course AS c ON c.c_id=sc.c_id
    GROUP BY s.s_id HAVING sc.s_score>70;
    
    # 正确处理方法:
    SELECT s.s_name,c.c_name,sc.s_score
    FROM student as s
    INNER JOIN score as sc on s.s_id=sc.s_id
    INNER JOIN course AS c ON c.c_id=sc.c_id
    WHERE sc.s_score>70;
    # 注:where 后面要跟的是数据表里的字段,where针对数据库文件的发挥作用,
    # 而having只是根据前面查询出来的结果集再次进行查询,因此having是针对结果集发挥作用。
    View Code
    40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩(重要top)

     
    SELECT s.s_id,s.s_name,c.c_name,c.c_id,sc.s_score
    FROM student as s
    INNER JOIN score as sc
    ON s.s_id=sc.s_id
    INNER JOIN course as c
    ON sc.c_id=c.c_id
    INNER JOIN teacher as t
    ON t.t_id=c.t_id
    WHERE t.t_name="张三" ORDER BY sc.s_score DESC limit 0,1; # 0表示从0开始取,若为降序排列则0是第一位,1表示取几条
    
    # SQL SERVER 中用top
    /*
    SELECT top 1 s.s_id,s.s_name,c.c_name,c.c_id
    FROM student as s
    INNER JOIN score as sc
    ON s.s_id=sc.s_id
    INNER JOIN course as c
    ON sc.c_id=c.c_id
    INNER JOIN teacher as t
    ON t.t_id=c.t_id
    WHERE t.t_name="张三" ORDER BY DESC
    */
    View Code
    
    
    
    
    
     





  • 相关阅读:
    HDU 6187 Destroy Walls
    HDU1596 find the safest road
    美国机遇号失联已久,NASA想出一奇招,网友看后:这我上我也行!
    萨拉飞机或掉入恐怖深渊,那里满是核废料
    Problem : 恢复一棵树
    Problem : [tju1071]一个简单题
    Problem : 马农
    人类首个“触日”探测器绕日第二圈
    美国三岁男孩森林迷路两天 遇黑熊“热心帮忙”终获救
    世上最孤独鸭子去世
  • 原文地址:https://www.cnblogs.com/wuxiping2019/p/12443216.html
Copyright © 2011-2022 走看看