MySQL 50题 精练 + 小总结

目录面试

1、数据表信息算法

2、建立数据库、表、填充信息sql

一、建立数据库并使用数据库

二、建立学生表并插入数据设计模式

三、建立教师表并插入数据架构

四、建立课程表并插入数据机器学习

五、建立成绩表并插入数据函数

3、精简50题 及 参考答案oop


免费赠送】我的整理关于MySQL知识的思惟导图:MySQL_思惟导图(全面).xmind.zip学习

免费赠送】我的整理关于MySQL索引的PPT:MySQL索引原理及如何创建高效索引.pptx

1、数据表信息

已知有如下4张表:

数据库、表信息说明
序号 表名称 字段信息 描述
1 学生表 student(s_id,  s_name,  s_birth,  s_sex) 学号,  学生姓名,  出生年月,  性别
2 成绩表 score(s_id,  c_id,  score) 学号,  课程号,  成绩
3 课程表 course(c_id,  c_name,  t_id) 课程号,  课程名称,  教师号
4 教师表 teacher(t_id,  t_name) 教师号,  教师姓名

以上4个表是经过有加粗的字段创建链接的。


2、建立数据库、表、填充信息

一、建立数据库并使用

【注意】:推荐库名与应用名称保持一致

-- 学校考试成绩库。库名与应用名称保持一致
DROP DATABASE IF EXISTS school_score;
CREATE DATABASE school_score;
-- 使用学校考试成绩库
USE school_score; 

二、建立学生表并插入数据

【注意】:

  1. 表必备三个字段,id、create_time、update_time
  2. 表名、字段名必段使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,由于没法进行预发布,因此字段名称须要慎重考虑
  3. 表名不使用复数名词

说明:其中 id 必为主键,类型为bigint unsigned、单表时自增、步长为1。create_time,update_time的类型均为 datetime 类型,前者如今时表示主动式建立,后者过去分词表示被动式更新。

-- 建立学生表
CREATE TABLE IF NOT EXISTS `student`(
    `id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键',
    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  	
    `s_id` VARCHAR(20) COMMENT '学生编号',
    `s_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '学生姓名',
    `s_birth` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '出生年月',
    `s_sex` ENUM('男', '女') NOT NULL DEFAULT '男' COMMENT '学生性别',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 插入学生表测试数据
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('01' , '赵雷' , '1990-01-01' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('02' , '钱电' , '1990-12-21' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('03' , '孙风' , '1990-05-20' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('04' , '李云' , '1990-08-06' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('05' , '周梅' , '1991-12-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('06' , '吴兰' , '1992-03-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('07' , '郑竹' , '1989-07-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('08' , '王菊' , '1990-01-20' , '女');

三、建立教师表并插入数据

-- 教师表
CREATE TABLE `teacher`(
    id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    
    `t_id` VARCHAR(20) COMMENT '教师编号',
    `t_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '教师姓名',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 教师表测试数据
INSERT INTO teacher (`t_id`, `t_name`) VALUES('01' , '张老师');
INSERT INTO teacher (`t_id`, `t_name`) VALUES('02' , '李老师');
INSERT INTO teacher (`t_id`, `t_name`) VALUES('03' , '王老师');

四、建立课程表并插入数据

-- 课程表
CREATE TABLE `course`(
    `id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键',
    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    
    `c_id`  VARCHAR(20) COMMENT '课程编号',
    `c_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '课程名称',
    `t_id` VARCHAR(20) NOT NULL COMMENT '教师编号',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 课程表测试数据
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('01' , '语文' , '02');
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('02' , '数学' , '01');
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('03' , '英语' , '03');

五、建立成绩表并插入数据

-- 成绩表
CREATE TABLE `score`(
    id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    
    `s_id` VARCHAR(20) COMMENT '学生编号',
    `c_id`  VARCHAR(20) COMMENT '课程编号',
    `s_score` INT(3) COMMENT '分数',
    PRIMARY KEY(id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
 
-- 成绩表测试数据
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '01' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '02' , 90);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '03' , 99);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '01' , 70);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '02' , 60);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '03' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '01' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '02' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '03' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '01' , 50);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '02' , 30);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '03' , 20);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('05' , '01' , 76);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('05' , '02' , 87);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('06' , '01' , 31);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('06' , '03' , 34);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('07' , '02' , 89);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('07' , '03' , 98);

数据状况截图说明:

上述建立库及表的脚本文件下载:MySQL 精简50题练习 school_score.sql


3、精简50题 及 参考答案

一、查询"01"课程比"02"课程成绩高的学生的学号及课程分数

-- 一、查询"01"课程比"02"课程成绩高的学生的学号及课程分数
SELECT a.s_id AS s_id, score1, score2
FROM 
(SELECT s_id, s_score AS score1 FROM score WHERE c_id = '01') a
INNER JOIN
(SELECT s_id, s_score AS score2 FROM score WHERE c_id = '02') b
ON a.s_id = b.s_id WHERE score1 > score2;

运行结果截图: 


二、查询"01"课程比"02"课程成绩高的学生的信息及课程分数

-- 二、查询"01"课程比"02"课程成绩高的学生的信息及课程分数
SELECT s.*, a.s_score AS score1, b.s_score AS score2
FROM student s,
     (SELECT s_id,s_score FROM score WHERE c_id = '01') a,
     (SELECT s_id,s_score FROM score WHERE c_id = '02') b
WHERE a.s_id = b.s_id AND a.s_score > b.s_score AND s.`s_id` = a.s_id;

运行结果截图: 


三、查询平均成绩大于等于60分的同窗的学生编号和学生姓名和平均成绩

-- 三、查询平均成绩大于等于60分的同窗的学生编号和学生姓名和平均成绩
SELECT s.`s_id`,s.`s_name`,AVG(s_score) AS avg_score 
FROM student AS s,score AS sc
WHERE s.`s_id` = sc.`s_id` 
GROUP BY s.`s_id`
HAVING avg_score >= 60;

运行结果截图: 


四、查询全部同窗的学生编号、学生姓名、选课总数、全部课程的总成绩(没成绩显示null)

这道题得用到left join,不能用where链接,由于题目说了要求有显示为null的,where是inner join,不会出现null,若是用where在这道题里会查不出第08号学生

-- 四、查询全部同窗的学生编号、学生姓名、选课总数、全部课程的总成绩(没成绩显示null)
SELECT s.`s_id`,s_name,COUNT(c_id)AS 选课总数,SUM(s_score) AS 总成绩
FROM student s
LEFT JOIN score sc
ON s.`s_id` = sc.`s_id`
GROUP BY s_id;

运行结果截图: 


五、查询姓“李”的老师的个数

-- 五、查询姓“李”的老师的个数
SELECT COUNT(t_name) AS 人数
FROM teacher 
WHERE t_name LIKE '李%';

运行结果截图: 


六、查询没学过“张三”老师课的学生的学号、姓名

-- 六、查询没学过“张老师”老师课的学生的学号、姓名
SELECT s_id, s_name FROM student WHERE s_id NOT IN
(SELECT s_id FROM score WHERE c_id IN
(SELECT c_id FROM course WHERE t_id IN 
(SELECT t_id 
FROM teacher 
WHERE t_name = '张老师')));

-- 法二
SELECT s_id, s_name 
FROM student
WHERE s_id NOT IN(SELECT sc.s_id FROM score sc
INNER JOIN course co ON sc.`c_id` = co.`c_id`
INNER JOIN teacher te ON co.`t_id`= te.`t_id`
WHERE te.`t_name`='张老师');

-- 法三
SELECT s_id, s_name
FROM student
WHERE s_name NOT IN (
    SELECT s.s_name
    FROM student AS s, course AS c, teacher AS t, score AS sc
    WHERE s.s_id = sc.s_id
        AND sc.c_id = c.c_id
        AND c.t_id = t.t_id
        AND t.t_name = '张老师');

运行结果截图: 


七、查询学过编号为“01”的课程而且也学过编号为“02”的课程的学生的学号、姓名

-- 七、查询学过编号为“01”的课程而且也学过编号为“02”的课程的学生的学号、姓名
SELECT s_id, s_name 
FROM student 
WHERE s_id IN (
SELECT s_id
FROM score
WHERE c_id = '01' OR c_id = '02'
GROUP BY s_id
HAVING COUNT(c_id) >= 2);

运行结果截图: 


八、查询课程编号为“02”的总成绩

--  八、查询课程编号为“02”的总成绩
SELECT SUM(s_score) AS 总成绩
FROM score
WHERE c_id = '02';

运行结果截图: 


九、查询没有学全全部课的学生的学号、姓名

-- 九、查询没有学全全部课的学生的学号、姓名
SELECT st.`s_id`,st.`s_name` 
FROM student st
INNER JOIN score sc
ON st.`s_id` = sc.`s_id`
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) < (SELECT
COUNT(DISTINCT c_id) 
FROM course);

运行结果截图: 


十、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名

-- 十、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名
SELECT st.`s_id`,st.`s_name`
FROM student st 
WHERE st.`s_id` IN(
SELECT DISTINCT sc.`s_id` 
FROM score sc
WHERE sc.`c_id` IN(
SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id` = 01)) AND
st.`s_id` <> '01';

-- 法二
SELECT DISTINCT st.`s_id`,st.`s_name`
FROM student st 
INNER JOIN score sc
ON st.`s_id`= sc.`s_id`
WHERE sc.`c_id` IN(
SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id` = '01') AND
st.`s_id` <> '01';

运行结果截图: 


十一、查询和“01”号同窗所学课程彻底相同的其余同窗的信息

-- 十一、查询和“01”号同窗所学课程彻底相同的其余同窗的信息
SELECT DISTINCT st.* 
FROM student st
INNER JOIN score sc
ON st.`s_id` = sc.`s_id`
WHERE sc.`c_id` IN
(SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id`= '01') AND  sc.`s_id` <> '01'
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) = (SELECT
COUNT(c_id) FROM score WHERE s_id = '01');

运行结果截图: 


十二、查询两门及其以上不及格课程的同窗的学号,姓名及其平均成绩

-- 十二、查询两门及其以上不及格课程的同窗的学号,姓名及其平均成绩
SELECT st.`s_id`,st.`s_name`,AVG(sc.s_score) AS avg_score
FROM student st, score sc 
WHERE st.`s_id` = sc.`s_id`
AND sc.`s_score` < 60
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) >= 2;

运行结果截图:


1三、检索"01"课程分数小于60,按分数降序排列的学生信息

-- 1三、检索"01"课程分数小于60,按分数降序排列的学生信息
SELECT st.*,sc.`s_score`
FROM student st
INNER JOIN score sc ON 
st.`s_id`= sc.`s_id` 
WHERE sc.`c_id` = '01' AND sc.`s_score` < 60
ORDER BY sc.`s_score` DESC;

运行结果截图:


1四、按平均成绩从高到低显示全部学生的全部课程的成绩以及平均成绩

-- 1四、按平均成绩从高到低显示全部学生的全部课程的成绩以及平均成绩
SELECT s_id, 
SUM(CASE WHEN c_id = '01' THEN s_score ELSE NULL END) AS score1,
SUM(CASE WHEN c_id = '02' THEN s_score ELSE NULL END) AS score2,
SUM(CASE WHEN c_id = '03' THEN s_score ELSE NULL END) AS score3,
AVG(s_score)
FROM score
GROUP BY s_id
ORDER BY AVG(s_score) DESC;

运行结果截图:


1五、查询各科成绩最高分、最低分、平均分、及格率、中等率、优良率、优秀率

  • 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列。
  • 以以下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。
  • 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
--  1五、查询各科成绩最高分、最低分、平均分、及格率、中等率、优良率、优秀率
--      要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
--      以以下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
--      及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 
-- 先从简单的写法开始,及格率直接用小数表示,没用百分号
SELECT co.c_id AS 课程ID, co.c_name AS 课程名称, COUNT(*) AS 选修人数, 
   MAX(s_score) AS 最高分 , MIN(s_score) AS 最低分, AVG(s_score) AS 平均分,
   SUM(CASE WHEN s_score >= 60 THEN 1 ELSE 0 END) / COUNT(*) AS  '及格率',
   SUM(CASE WHEN s_score BETWEEN 70 AND 80 THEN 1 ELSE 0 END) / COUNT(*) AS  '中等率',
   SUM(CASE WHEN s_score BETWEEN 80 AND 90 THEN 1 ELSE 0 END) / COUNT(*) AS  '优良率',
   SUM(CASE WHEN s_score >= 90 THEN 1 ELSE 0 END) / COUNT(*) AS  '优秀率'
FROM score sc, course co
WHERE sc.c_id = co.c_id	
GROUP BY co.c_id
ORDER BY COUNT(*) DESC, co.c_id;

-- 复杂点的写法,及格率用百分号表示
SELECT a.c_id AS '课程ID', course.c_name AS '课程name', COUNT(*) AS 选修人数,
       MAX(a.s_score) AS '最高分',  MIN(a.s_score) AS '最低分',
       CAST(AVG(a.s_score) AS DECIMAL(5,2)) AS '平均分',
       CONCAT(CAST(SUM(pass)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '及格率',
       CONCAT(CAST(SUM(medi)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '中等率',
       CONCAT(CAST(SUM(good)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '优良率',
       CONCAT(CAST(SUM(excellent)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '优秀率' 
FROM
    (SELECT * ,
        CASE WHEN s_score>=60 THEN 1 ELSE 0 END AS pass,
        CASE WHEN s_score>=70 AND s_score<80 THEN 1 ELSE 0 END AS medi,
        CASE WHEN s_score>=80 AND s_score<90 THEN 1 ELSE 0 END AS good,
        CASE WHEN s_score>=90 THEN 1 ELSE 0 END AS excellent
     FROM score) a
LEFT JOIN course ON a.c_id=course.c_id
GROUP BY a.c_id
ORDER BY COUNT(*) DESC, a.c_id;

运行结果截图:


1六、按平均成绩进行排序,显示总排名和各科排名,Score 重复时保留名次空缺

  • Score 重复时保留名次空缺,指的是rank()和dense_rank()的区别,也就是两个并列第一名以后的那我的是第三名(rank)仍是第二名(dense_rank)的区别。
-- 1六、按平均成绩进行排序,显示总排名和各科排名,Score 重复时保留名次空缺
SELECT s.*, rank_01, rank_02, rank_03, rank_total
FROM student s
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_01 FROM score WHERE c_id=01) A ON s.s_id=A.s_id
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_02 FROM score WHERE c_id=02) B ON s.s_id=B.s_id
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_03 FROM score WHERE c_id=03) C ON s.s_id=C.s_id
LEFT JOIN (SELECT s_id, rank() over(ORDER BY AVG(s_score) DESC) AS rank_total FROM score GROUP BY s_id) D ON s.s_id=D.s_id
ORDER BY rank_total ASC;

运行结果截图:


1七、按各科成绩进行排序,并显示排名

-- 1七、按各科成绩进行排序,并显示排名
SELECT a.`c_id`,a.`s_id`,a.`s_score`,COUNT(b.`s_score`)+1 AS rank 
FROM score a
LEFT JOIN score b
ON a.`s_score`< b.`s_score` AND a.`c_id`= b.`c_id`
GROUP BY a.`c_id`,a.`s_id`,a.`s_score`
ORDER BY a.`c_id`,rank;

运行结果截图:


1八、查询学生的总成绩并进行排名

-- 1八、查询学生的总成绩并进行排名
SELECT a.*, @rank:= @rank+1 AS rank 
FROM 
  (SELECT s_id,SUM(s_score)
    FROM score 
    GROUP BY s_id 
    ORDER BY SUM(s_score) DESC) a,
  (SELECT @rank:=0) b;

运行结果截图:


1九、查询不一样老师所教不一样课程平均分从高到低显示

-- 1九、查询不一样老师所教不一样课程平均分从高到低显示
SELECT te.`t_id`, te.`t_name`, AVG(sc.`s_score`)
FROM score sc INNER JOIN course co ON sc.`c_id`= co.`c_id`
INNER JOIN teacher te ON co.`t_id`= te.`t_id`
GROUP BY te.`t_id`
ORDER BY AVG(sc.`s_score`) DESC;

运行结果截图:


20、查询全部课程的成绩第2名到第3名的学生信息及该课程成绩

--  20、查询全部课程的成绩第2名到第3名的学生信息及该课程成绩
SELECT result.c_id, result.s_id, result.s_score, student.`s_name`,student.`s_birth`,student.`s_sex`
FROM 
(SELECT *, IF(@pa=a.c_id, @rank:= @rank+1, @rank:=1) AS rank, @pa:=a.c_id
FROM 
(SELECT c_id, s_id, s_score FROM score
GROUP BY c_id, s_id ORDER BY c_id, s_score DESC) a,
(SELECT @rank:=0, @pa:=NULL) b) result
LEFT JOIN student ON result.s_id = student.`s_id`
WHERE rank BETWEEN 2 AND 3
GROUP BY c_id, s_score DESC;

运行结果截图:


2一、使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称

--  2一、使用分段[85-100],[70-84],[60-69],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称
SELECT a.c_id AS '课程编号',course.c_name AS '课程名称',
SUM(level1) AS '[85-100]人数', SUM(level1)/COUNT(1) AS '[85-100]占比',
SUM(level2) AS '[70-84]人数', SUM(level2)/COUNT(1) AS '[70-84]占比',
SUM(level3) AS '[60-69]人数', SUM(level3)/COUNT(1) AS '[60-69]占比',
SUM(level4) AS '[0-59]人数', SUM(level4)/COUNT(1) AS '[0-59]占比' FROM
(SELECT *,
(CASE WHEN s_score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS 'level1',
(CASE WHEN s_score BETWEEN 70 AND 84 THEN 1 ELSE 0 END) AS 'level2',
(CASE WHEN s_score BETWEEN 60 AND 69 THEN 1 ELSE 0 END) AS 'level3',
(CASE WHEN s_score BETWEEN 0 AND 59 THEN 1 ELSE 0 END) AS 'level4'
FROM score) a
LEFT JOIN course ON a.c_id=course.c_id
GROUP BY a.c_id;

运行结果截图:


2二、查询学平生均成绩及其名次

-- 2二、查询学平生均成绩及其名次
SELECT a.*,@rank:=@rank+1 AS rank
FROM 
  (SELECT s_id, AVG(s_score) AS '平均成绩' 
  FROM score 
  GROUP BY s_id
  ORDER BY AVG(s_score) DESC) a,
  (SELECT @rank:=0) b;

运行结果截图:


2三、查询各科成绩前三名的记录

-- 2三、查询各科成绩前三名的记录
SELECT a.`c_id`,a.`s_id`,a.`s_score`
FROM score a
WHERE
  (SELECT COUNT(b.s_id) FROM score b WHERE a.`c_id`=b.`c_id` AND a.`s_score`< b.`s_score`) < 3
GROUP BY a.`c_id`, a.`s_id`;

运行结果截图:


2四、查询每门课程被选修的学生数

-- 2四、查询每门课程被选修的学生数
SELECT c_id, COUNT(s_id) AS '选修人数'
FROM score
GROUP BY c_id;

运行结果截图:


2五、 查询出只有两门课程的所有学生的学号和姓名

-- 2五、 查询出只有两门课程的所有学生的学号和姓名
SELECT s_id,s_name 
FROM student 
WHERE s_id IN(
SELECT s_id 
FROM score 
GROUP BY s_id
HAVING COUNT(c_id)=2);

运行结果截图:


2六、查询男生、女生人数

-- 2六、查询男生、女生人数
SELECT s_sex AS '性别',COUNT(*) AS  '人数'
FROM student
GROUP BY s_sex;

运行结果截图:


2七、查询名字中含有"风"字的学生信息

-- 2七、查询名字中含有"风"字的学生信息
SELECT * 
FROM student 
WHERE s_name LIKE '%风%';

运行结果截图:


2八、查询同名同姓学生名单,并统计同名人数

-- 2八、查询同名同姓学生名单,并统计同名人数
SELECT s_name, num AS '同名人数'
FROM (
  SELECT *, COUNT(s_id) -1 AS num 
  FROM student
  GROUP BY s_name) a;

运行结果截图:


2九、查询1990年出生的学生名单

-- 2九、查询1990年出生的学生名单
SELECT *
FROM student
WHERE YEAR(s_birth) = '1990';

运行结果截图:


30、查询平均成绩大于等于85的全部学生的学号、姓名和平均成绩

-- 30、查询平均成绩大于等于85的全部学生的学号、姓名和平均成绩
SELECT st.`s_id` AS '学号',st.`s_name` AS '姓名',AVG(s_score) AS '平均成绩'
FROM student st
INNER JOIN score sc 
ON st.`s_id`=sc.`s_id`
GROUP BY sc.`s_id`
HAVING AVG(s_score)>= 85;

运行结果截图:


3一、查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列

-- 3一、查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
SELECT c_id, AVG(s_score) AS '平均成绩'
FROM score
GROUP BY c_id
ORDER BY AVG(s_score),c_id DESC;

运行结果截图:


3二、查询课程名称为"数学",且分数低于60的学生姓名和分数

-- 3二、查询课程名称为"数学",且分数低于60的学生姓名和分数
SELECT st.`s_id`, st.`s_name`, s_score 
FROM student st
INNER JOIN score sc
ON st.`s_id`=sc.`s_id`
WHERE s_score < 60 AND sc.`c_id` IN (
SELECT c_id 
FROM course 
WHERE c_name = '数学');

运行结果截图:


3三、查询全部学生的课程及分数状况

-- 3三、查询全部学生的课程及分数状况
SELECT sc.`s_id`,
SUM(CASE WHEN co.c_name = '语文' THEN sc.s_score ELSE NULL END) AS '语文成绩',
SUM(CASE WHEN co.c_name = '数学' THEN sc.s_score ELSE NULL END) AS '数学成绩',
SUM(CASE WHEN co.c_name = '英语' THEN sc.s_score ELSE NULL END) AS '英语成绩'
FROM score sc INNER JOIN course co ON sc.`c_id`= co.`c_id`
GROUP BY sc.`s_id`;

运行结果截图:


3四、查询任何一门课程成绩在70分以上的姓名、课程名称和分数

-- 3四、查询任何一门课程成绩在70分以上的姓名、课程名称和分数
SELECT st.`s_name` AS '姓名', co.`c_name` AS '课程名称',sc.`s_score` AS '分数'
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id`
INNER JOIN course co ON sc.`c_id`= co.`c_id`
WHERE sc.`s_score` >= 70;

运行结果截图:


3五、查询不及格的课程并按课程号从大到小排列

-- 3五、查询不及格的课程并按课程号从大到小排列
SELECT co.`c_id`,co.`c_name`,sc.`s_score`
FROM course co
INNER JOIN score sc ON co.`c_id`=sc.`c_id`
WHERE s_score < 60
ORDER BY c_id DESC;

运行结果截图:


3六、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名

-- 3六、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
SELECT st.`s_id` AS '学号',st.`s_name` AS '姓名'
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id` 
WHERE c_id = '03' AND s_score > 80;

运行结果截图:


3七、求每门课程的学生人数

-- 3七、求每门课程的学生人数
SELECT c_id, COUNT(s_id) AS '选课人数'
FROM score
GROUP BY c_id;

运行结果截图:


3八、成绩不重复,查询选修“张老师”老师所授课程的学生中成绩最高的学生姓名及其成绩

-- 3八、成绩不重复,查询选修“张老师”老师所授课程的学生中成绩最高的学生姓名及其成绩
SELECT st.`s_id` AS '学号' , st.`s_name` AS '姓名' ,MAX(sc.`s_score`) AS '成绩' 
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id`
WHERE sc.`c_id` IN (SELECT c_id
               FROM course
               WHERE t_id IN (SELECT t_id
                              FROM teacher 
                              WHERE t_name = '张老师'
                              ));

运行结果截图:


3九、成绩有重复的状况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩

-- 3九、成绩有重复的状况下,查询选修「张老师」老师所授课程的学生中,成绩最高的学生信息及其成绩
SELECT * FROM
    (SELECT *, DENSE_RANK() over(ORDER BY s_score DESC) A
    FROM score
    WHERE c_id = (SELECT c_id FROM course WHERE t_id = (SELECT t_id FROM teacher WHERE t_name='张老师'))
) B
WHERE B.A=1;

运行结果截图:


40、查询不一样课程成绩相同的学生的学生编号、课程编号、学生成绩

-- 40、查询不一样课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT a.`s_id`,a.`c_id`,b.`c_id`,a.`s_score`,b.`s_score`
FROM score a, score b
WHERE a.`s_id`= b.`s_id` AND a.`s_score`= b.`s_score` AND a.`c_id`<> b.`c_id`;

运行结果截图:


4一、查询每门功课成绩最好的前两名

-- 4一、查询每门功课成绩最好的前两名
(SELECT * FROM score WHERE c_id = '01' ORDER BY s_score DESC LIMIT 2)
UNION 
(SELECT * FROM score WHERE c_id = '02' ORDER BY s_score DESC LIMIT 2)
UNION
(SELECT * FROM score WHERE c_id = '03' ORDER BY s_score DESC LIMIT 2);

运行结果截图:


4二、统计每门课程的学生选修人数(超过5人的课程才统计)

要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列。

-- 4二、统计每门课程的学生选修人数(超过5人的课程才统计)。
-- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT c_id,COUNT(s_id) AS '选修人数'
FROM score
GROUP BY c_id
HAVING COUNT(s_id) >= 5
ORDER BY COUNT(s_id) DESC, c_id;

运行结果截图:


4三、检索至少选修两门课程的学生学号

-- 4三、检索至少选修两门课程的学生学号
SELECT s_id, COUNT(c_id) AS '选修课程数'
FROM score 
GROUP BY s_id
HAVING COUNT(c_id) >= 2;

运行结果截图:


4四、查询选修了所有课程的学生信息

-- 4四、查询选修了所有课程的学生信息
SELECT * 
FROM student 
WHERE s_id IN (
  SELECT s_id
  FROM score
  GROUP BY s_id
  HAVING COUNT(c_id) = (SELECT COUNT(DISTINCT c_id) FROM course));

运行结果截图:


4五、查询各学生的年龄

-- 4五、查询各学生的年龄
SELECT s_id,
       s_name,
       (YEAR(NOW()) - YEAR(s_birth)) AS '年龄'
FROM student;

运行结果截图:


4六、按照出生日期来算,当前月日 < 出生年月的月日,则年龄减一

TIMESTAMPDIFF函数:有参数设置,能够精确到年(YEAR)、天(DAY)、小时(HOUR),分钟(MINUTE)和秒(SECOND),使用起来比datediff函数更加灵活。对于比较的两个时间,时间小的放在前面,时间大的放在后面。

datediff函数:返回值是相差的天数,不能定位到小时、分钟和秒。

-- 4六、按照出生日期来算,当前月日 < 出生年月的月日,则年龄减一
SELECT s_id,
       s_name,
       TIMESTAMPDIFF(YEAR,s_birth,NOW()) AS '年龄'
FROM student;

运行结果截图:


4七、查询本周过生日的学生

  • week(时间) 默认从0开始,并却星期天默认为第一天,国外的算法
  • week(时间,1) 从1开始,并却星期一为第一天,国内算法
-- 4七、查询本周过生日的学生
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW());

-- 以周一为一周的开始
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW(),1);

运行结果截图:


4八、查询下周过生日的学生

-- 4八、查询下周过生日的学生
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW())+1;

-- 以周一为一周的开始
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW(),1)+1;

运行结果截图:


4九、查询本月过生日的学生

-- 4九、查询本月过生日的学生
SELECT *
FROM student
WHERE MONTH(s_birth) = MONTH(NOW());

运行结果截图:


50、查询下个月过生日的学生

--  50、查询下个月过生日的学生
SELECT *
FROM student
WHERE MONTH(s_birth) = MONTH(NOW())+1;

运行结果截图:


文章最后,给你们推荐一些受欢迎的技术博客连接

  1. JAVA相关的深度技术博客连接
  2. Flink 相关技术博客连接
  3. Spark 核心技术连接
  4. 设计模式 —— 深度技术博客连接
  5. 机器学习 —— 深度技术博客连接
  6. Hadoop相关技术博客连接
  7. 超全干货--Flink思惟导图,花了3周左右编写、校对
  8. 深刻JAVA 的JVM核心原理解决线上各类故障【附案例】
  9. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  10. 聊聊RPC通讯,常常被问到的一道面试题。源码+笔记,包懂
  11. 深刻聊聊Java 垃圾回收机制【附原理图及调优方法】

欢迎扫描下方的二维码或 搜索 公众号“大数据高级架构师”,咱们会有更多、且及时的资料推送给您,欢迎多多交流!

                                           

       

相关文章
相关标签/搜索