0
点赞
收藏
分享

微信扫一扫

sql50题

草原小黄河 2022-03-17 阅读 72

`

环境

/*
 Navicat Premium Data Transfer

 Source Server         : ssmbuild
 Source Server Type    : MySQL
 Source Server Version : 50716
 Source Host           : localhost:3306
 Source Schema         : sqldemo

 Target Server Type    : MySQL
 Target Server Version : 50716
 File Encoding         : 65001

 Date: 17/03/2022 22:31:40
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for Course
-- ----------------------------
DROP TABLE IF EXISTS `Course`;
CREATE TABLE `Course` (
  `c_id` varchar(20) COLLATE utf8_bin NOT NULL,
  `c_name` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '',
  `t_id` varchar(20) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of Course
-- ----------------------------
BEGIN;
INSERT INTO `Course` VALUES ('01', '语文', '02');
INSERT INTO `Course` VALUES ('02', '数学', '01');
INSERT INTO `Course` VALUES ('03', '英语', '03');
COMMIT;

-- ----------------------------
-- Table structure for Score
-- ----------------------------
DROP TABLE IF EXISTS `Score`;
CREATE TABLE `Score` (
  `s_id` varchar(20) COLLATE utf8_bin NOT NULL,
  `c_id` varchar(20) COLLATE utf8_bin NOT NULL,
  `s_score` int(3) DEFAULT NULL,
  PRIMARY KEY (`s_id`,`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of Score
-- ----------------------------
BEGIN;
INSERT INTO `Score` VALUES ('01', '01', 80);
INSERT INTO `Score` VALUES ('01', '02', 90);
INSERT INTO `Score` VALUES ('01', '03', 99);
INSERT INTO `Score` VALUES ('02', '01', 70);
INSERT INTO `Score` VALUES ('02', '02', 60);
INSERT INTO `Score` VALUES ('02', '03', 80);
INSERT INTO `Score` VALUES ('03', '01', 80);
INSERT INTO `Score` VALUES ('03', '02', 80);
INSERT INTO `Score` VALUES ('03', '03', 80);
INSERT INTO `Score` VALUES ('04', '01', 50);
INSERT INTO `Score` VALUES ('04', '02', 30);
INSERT INTO `Score` VALUES ('04', '03', 20);
INSERT INTO `Score` VALUES ('05', '01', 76);
INSERT INTO `Score` VALUES ('05', '02', 87);
INSERT INTO `Score` VALUES ('06', '01', 31);
INSERT INTO `Score` VALUES ('06', '03', 34);
INSERT INTO `Score` VALUES ('07', '02', 89);
INSERT INTO `Score` VALUES ('07', '03', 98);
COMMIT;

-- ----------------------------
-- Table structure for Student
-- ----------------------------
DROP TABLE IF EXISTS `Student`;
CREATE TABLE `Student` (
  `s_id` varchar(20) COLLATE utf8_bin NOT NULL,
  `s_name` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '',
  `s_birth` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '',
  `s_sex` varchar(10) COLLATE utf8_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of Student
-- ----------------------------
BEGIN;
INSERT INTO `Student` VALUES ('01', '赵雷', '1990-01-01', '男');
INSERT INTO `Student` VALUES ('02', '钱电', '1990-12-21', '男');
INSERT INTO `Student` VALUES ('03', '孙风', '1990-05-20', '男');
INSERT INTO `Student` VALUES ('04', '李云', '1990-08-06', '男');
INSERT INTO `Student` VALUES ('05', '周梅', '1991-12-01', '女');
INSERT INTO `Student` VALUES ('06', '吴兰', '1992-03-01', '女');
INSERT INTO `Student` VALUES ('07', '郑竹', '1989-07-01', '女');
INSERT INTO `Student` VALUES ('08', '王菊', '1990-01-20', '女');
COMMIT;

-- ----------------------------
-- Table structure for Teacher
-- ----------------------------
DROP TABLE IF EXISTS `Teacher`;
CREATE TABLE `Teacher` (
  `t_id` varchar(20) COLLATE utf8_bin NOT NULL,
  `t_name` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '',
  PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

-- ----------------------------
-- Records of Teacher
-- ----------------------------
BEGIN;
INSERT INTO `Teacher` VALUES ('01', '张三');
INSERT INTO `Teacher` VALUES ('02', '李四');
INSERT INTO `Teacher` VALUES ('03', '王五');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

1、

-- 1.查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号(重点)
-- 思路:  首先构建两个表a,b   a 查询出全部学生课程01的成绩   b 查询出全部学生课程02的成绩
-- 然后两个表进行连接  条件就是 课程编号为“01”的课程比“02”的课程成绩高

select a.s_id "s_no" ,a.s_score "01",b.s_score "02" from (
select s_id,c_id,s_score from Score where c_id = '01'   -- 首先先把课程为01的学生的成绩都找出来
) as a
inner JOIN (
select s_id,c_id,s_score from Score where c_id = '02'   -- 把课程为02的学生的成绩都找出来
) as b on a.s_id = b.s_id
where a.s_score > b.s_score

-- 再查出相关的姓名
select a.s_id "s_no",c.s_name "姓名",a.s_score "01",b.s_score "02" from (
select s_id,c_id,s_score from Score where c_id = '01'   -- 首先先把课程为01的学生的成绩都找出来
) as a
inner JOIN (
select s_id,c_id,s_score from Score where c_id = '02'   -- 把课程为02的学生的成绩都找出来
) as b on a.s_id = b.s_id
INNER JOIN Student as c on c.s_id=a.s_id
where a.s_score > b.s_score

2、

-- 2、查询平均成绩大于60分的学生的学号和平均成绩(简单,第二道重点)

select s_id,avg(s_score) from Score 
GROUP BY Score.s_id HAVING avg(s_score) > 60

3、

-- 3、查询所有学生的学号、姓名、选课数、总成绩

select a.s_id,a.s_name,COUNT(b.c_id),SUM(case when b.s_score is null then 0 else b.s_score end)
from Student as a
LEFT JOIN Score as b
on a.s_id = b.s_id
GROUP BY a.s_id,a.s_name

4、

-- 4、查询姓“猴”的老师的个数
select COUNT(t.t_name)
from Teacher as t where 
t.t_name like '猴%'

5、

-- 查询没学过“张三”老师课的学生的学号、姓名
-- 方法1
select s_id,s_name from Student
where s_id  not in
(
select s_id from Score
where c_id = (
select c_id
from Course where 
t_id = (
select t_id
from Teacher
where t_name = '张三'
)
)
)

-- 方法2
select s_id,s_name
from Student
where s_id not in (
select s_id from Score as s
INNER JOIN Course as c on s.c_id =c.c_id 
INNER JOIN Teacher as t on c.t_id = t.t_id
where t.t_name='张三'
)

6、

-- 6、查询学过“张三”老师所教的所有课的同学的学号、姓名  与题5类似

select s_id,s_name from Student where s_id in (
select s_id from Score
where c_id = 
(
select c_id from Course
where t_id = (
select t_id from Teacher
where t_name = '张三'
)
)
)

7、

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

select s_id,s_name from Student
where s_id in (
select a.s_id from 
(select s_id from Score where c_id = '01') as a
INNER JOIN
(select s_id from Score where c_id = '02') as b
on a.s_id = b.s_id
)

8、

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

select sum(s_score) from Score where c_id = '02'

9、

-- 9、查询所有课程成绩小于60分的学生的学号、姓名

select DISTINCT a.s_id,a.s_name from Student as a
LEFT JOIN Score as b on a.s_id = b.s_id 
 where b.s_score <'60'


select a.s_id,a.s_name from Student as a
where s_id in (
select s_id from Score where s_score < '60'
GROUP  BY s_id
)

10、

-- 10.查询没有学全所有课的学生的学号、姓名

-- 错误解法 没有考虑全部都没有选课的同学
select b.s_id,a.s_name from Student as a right JOIN 
(select s_id
from Score 
GROUP BY s_id 
HAVING count(c_id) <  (select count(c_id) from Course ))
 as b 
 on a.s_id = b.s_id

-- 正确解法
select st.s_id,st.s_name
from Student as st
LEFT JOIN Score as sc on st.s_id = sc.s_id
GROUP BY st.s_id HAVING count(DISTINCT sc.c_id) < (SELECT COUNT(DISTINCT c_id) from Course)

11、

-- 11、查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名
select b.s_id,a.s_name from Student as a
RIGHT JOIN 
(select DISTINCT s_id from Score where c_id in 
(
select c_id from Score where s_id = '01'
))
as b
on a.s_id = b.s_id
where a.s_id != '01'


select s_id,s_name from Student where s_id in (
select DISTINCT s_id from Score where c_id in 
(
select c_id from Score where s_id = '01'
) and s_id != '01')

12、

-- 12.查询和“01”号同学所学课程完全相同的其他同学的学号

select s_id from Student 
where s_id in (
select s_id from Score
where s_id != '01'
GROUP BY s_id having count(DISTINCT c_id) = (select count(DISTINCT c_id) from Score where s_id = '01')
)
and s_id not in (
select c_id from 
Score where c_id not in
(select c_id from Score where s_id = '01'
)
)

13、

-- 13、查询没学过"张三"老师讲授的任一门课程的学生姓名 和47题一样

select s_id,s_name from Student
where s_id not in (
select s_id from Score where c_id = (
select c_id from Course where t_id = 
(select t_id from Teacher where t_name = '张三')
)
)

14、


15、

-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select a.s_id,a.s_name,b.s_score from Student as a
INNER JOIN (
select s_id,avg(s_score) as s_score from Score where s_score <'60'
GROUP BY s_id  HAVING count(c_id) >= 2
)
as b
on a.s_id = b.s_id

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 as s_score from Score where s_score <'60'
GROUP BY s_id  HAVING count(DISTINCT c_id) >= 2
)
GROUP BY s_id , s_name

16、

-- 16、检索"01"课程分数小于60,按分数降序排列的学生信息
select * from Student as a
RIGHT JOIN (
select s_id from Score where c_id = '01' and s_score < '60'
ORDER BY s_score DESC
)as b 
on  a.s_id = b.s_id


select t.*,s.c_id,s.s_score 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 

17、

-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

select * from Score as a
LEFT JOIN
(select s_id,avg(s_score) as avg_s_score from Score 
GROUP BY s_id)
as b
on a.s_id = b.s_id 
order BY b.avg_s_score desc

-- 方式二  更好的
select s_id "学号",
max(CASE WHEN c_id = '01' THEN s_score	ELSE	0 END) "语文",
max(CASE WHEN c_id = '02' THEN s_score	ELSE	0 END) "数学",
max(CASE WHEN c_id = '03' THEN s_score	ELSE	0 END) "英语",
avg(s_score)
from Score
GROUP BY s_id
ORDER BY avg(s_score) DESC

18、

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

select s.c_id,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 Score as s
INNER JOIN Course as c 
on s.c_id = c.c_id
GROUP BY c_id

19、

-- 19、按各科成绩进行排序,并显示排名

select s_id,c_id,s_score,row_number() over (ORDER BY s_score desc)
from Score

20、

-- 20、查询学生的总成绩并进行排名
select s_id,sum(s_score) from Score 
GROUP BY s_id 
ORDER BY sum(s_score)desc

21、

-- 21 、查询不同老师所教不同课程平均分从高到低显示
--  自  以课程为主体 求平均分
select t_name,su.c_name,avg_score from Teacher as t
LEFT JOIN (
select c.c_id,t_id,c_name,avg(s_score)  as avg_score from Score as s,Course as c where s.c_id = c.c_id
GROUP BY c.c_id,c_name
) as su
on su.t_id = t.t_id
ORDER BY avg_score desc

-- 以老师为主体  老师教的课程多的情况 一个老师教多门课
select t.t_id,t.t_name,avg(sc.s_score) as avg_score
from Score as sc
INNER JOIN Course as c on sc.c_id = c.c_id
INNER JOIN Teacher as t on c.t_id = t.t_id
GROUP BY t.t_id,t.t_name
ORDER BY avg_score desc

22、

-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

select * 
from (
select st.s_id,st.s_name,st.s_birth,st.s_sex,c_id,s_core,row_number() over(partition by c_id ORDER BY s_core desc) m
from Score sc INNER JOIN Student st on sc.c_id = st.s_id
) a 
where m in (2,3)

23、

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

select a.c_id,c_name,t as '[<60]',y as '[70-60]',u as '[85-70]', i as '[100-85]' from Course as a
INNER JOIN
(
select c_id,
sum(CASE WHEN s_score<=60 THEN 1 ELSE 0 END) as t ,
sum(CASE WHEN s_score>60 and s_score <= 70 THEN 1 ELSE 0 END) as y ,
sum(CASE WHEN s_score>70 and s_score <=85  THEN 1 ELSE 0 END) as u ,
sum(CASE WHEN s_score>85 and s_score <=100  THEN 1 ELSE 0 END) as i 
from Score 
GROUP BY c_id
) as b
on a.c_id = b.c_id

-- Up答案
select c.c_id,c.c_name,
sum(CASE WHEN sc.s_score<=60 THEN 1 ELSE 0 END)  as "[<60]",
sum(CASE WHEN sc.s_score>60 and sc.s_score <= 70 THEN 1 ELSE 0 END) as "[70-60]",
sum(CASE WHEN sc.s_score>70 and sc.s_score <=85  THEN 1 ELSE 0 END) as "[85-70]" ,
sum(CASE WHEN sc.s_score>85 and sc.s_score <=100  THEN 1 ELSE 0 END)  as "[100-85]" 
from Score as sc
INNER JOIN Course as c on sc.c_id = c.c_id 
GROUP BY c.c_id ,c.c_name

24、

-- 24、查询学生平均成绩及其名次

select s_id ,avg(s_score),row_number () over (ORDER BY avg(s_score) desc)
from Score
GROUP BY s_id

25、排列

-- 25、查询各科成绩前三名的记录(不考虑成绩并列情况)



26、

-- 26、查询每门课程被选修的学生数
select sc.c_id,c.c_name,count(DISTINCT sc.s_id) from Score as sc 
INNER JOIN Course as c 
on sc.c_id = c.c_id
GROUP BY sc.c_id,c.c_name

27、

-- 27、 查询出只有两门课程的全部学生的学号和姓名
-- 方式1
select st.s_id,st.s_name from Student as st
INNER JOIN Score as sc
on st.s_id = sc.s_id
GROUP BY st.s_id HAVING count(DISTINCT sc.c_id) = '2'

-- 方式2  in的方式效率会低
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
)

28、

-- 28、查询男生、女生人数

select sum(CASE WHEN s_sex = '男' THEN 1 ELSE 0 END) as '男生数量' ,
sum(CASE WHEN s_sex = '女' THEN 1 ELSE 0 END) as '女生数量' 
from Student 

select s_sex,count(DISTINCT s_id) from Student
GROUP BY s_sex

29、

-- 29 查询名字中含有"风"字的学生信息
select * from Student
where s_name like '%风%'

30、


31、

-- 31、查询1990年出生的学生名单

select * from Student
where YEAR(s_birth) = '1990'

32、

-- 32、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩

select st.s_id,st.s_name,avg(sc.s_score) from Student as st
INNER JOIN Score as sc 
on st.s_id = sc.s_id
GROUP BY s_id HAVING avg(sc.s_score) >= 85

33、

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

select s.c_id,c.c_name,avg(s.s_score) from Score as s
INNER JOIN Course as c on s.c_id = c.c_id
GROUP BY s.c_id 
ORDER BY avg(s_score) asc , s.c_id desc

34、

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

select a.s_id,a.s_name,b.s_score from Student as a
INNER JOIN  
(
select s_id,s_score from Score where 
c_id = (
select c_id from Course where c_name = '数学'
) and s_score < 60
)
as b on a.s_id = b.s_id 

-- up答案
select s.s_id,s.s_score,st.s_name
from Score as s
INNER JOIN Course as c on s.c_id = c.c_id
INNER JOIN Student as st on s.s_id = st.s_id
where c.c_name = "数学" and s.s_score < 60

35、

-- 35、查询所有学生的课程及分数情况(重点)

-- 需要注意的是 在分组的时候 case when 只会去匹配的时候只会返回到第一条 因为其他的都是不满足条件的
-- 可以使用一个max去返回  因为最大的那个有值

select sd.s_id ,sd.s_name,
max(case when c.c_name = '语文' then s.s_score else null end) as '语文',
max(case when c.c_name = '数学' then s.s_score else null end) as '数学',
max(case when c.c_name = '英语' then s.s_score else null end) as '英语'
from Score as s
INNER JOIN Course as c on s.c_id = c.c_id
INNER JOIN Student as sd on s.s_id = sd.s_id
GROUP BY sd.s_id ,sd.s_name

36、

-- 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数
select st.s_name,sc.c_id,co.c_name,sc.s_score from Student  as st
INNER JOIN Score as sc on st.s_id = sc.s_id
INNER JOIN Course as co on sc.c_id = co.c_id
where sc.s_score > 70

select st.s_id,st.s_name,
max(case when co.c_name = '语文' then sc.s_score else null end) as '语文',
max(case when co.c_name = '数学' then sc.s_score else null end) as '数学',
max(case when co.c_name = '英语' then sc.s_score else null end) as '英语'
from Student as st
INNER JOIN Score as sc on st.s_id = sc.s_id
INNER JOIN Course as co  on sc.c_id = co.c_id
where sc.s_score > 70
GROUP BY st.s_id,st.s_name

37、

-- 37、查询不及格的课程并按课程号从大到小排列
select st.s_id,st.s_name,sc.c_id,co.c_name,sc.s_score FROM Student as st
INNER JOIN(
select * from Score where s_score < 60
) as sc 
on st.s_id = sc.s_id
INNER JOIN Course as co
on sc.c_id = co.c_id
order by sc.c_id desc

38、

-- 38、查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
select st.s_id,st.s_name from Student as st
where s_id in (
select s_id from Score where c_id = 03 and s_score > 80
)

39、

-- 39、求每门课程的学生人数

select c.c_id,c.c_name, count(DISTINCT s_id) from Score as s
INNER JOIN Course as c on c.c_id = s.c_id
GROUP BY c.c_id,c.c_name

40、

-- 40、查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩

select st.s_name,te.t_name,sc.s_score from Student as st
INNER JOIN Score as sc on st.s_id = sc.s_id
INNER JOIN Course as co on sc.c_id = co.c_id
INNER JOIN Teacher as te on co.t_id = te.t_id
where te.t_name = '张三'
ORDER BY sc.s_score DESC LIMIT 0,1

41、

-- 41.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select s_id from (
select b.s_id,b.s_score from Score as b

INNER JOIN (
select s_id from Score
GROUP BY s_id HAVING count(DISTINCT c_id) > 1
) as c on b.s_id = c.s_id
GROUP BY b.s_id, b.s_score
) as a
GROUP BY s_id HAVING count(s_id) = 1

42、排列

-- 42、查询每门功成绩最好的前两名

43、

-- 43、统计每门课程的学生选修人数(超过5人的课程才统计)。
-- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

select c_id,case when count(s_score) > 5 then count(s_score) else null end
as coun from Score
GROUP BY c_id 
ORDER BY coun DESC,c_id desc

select c_id,count(DISTINCT s_id) as cnt from Score
GROUP BY c_id HAVING cnt > 5
ORDER BY cnt desc,c_id desc

44、

-- 44、检索至少选修两门课程的学生学号

select st.s_id,st.s_name,count(sc.s_score) from Student as st
INNER JOIN Score as sc
on st.s_id = sc.s_id
GROUP BY sc.s_id HAVING count(sc.s_score) >= 2

select s_id,count(DISTINCT c_id) as cnt FROM Score
GROUP BY s_id HAVING cnt >=2

45、

-- 45、 查询选修了全部课程的学生信息
select * from Student
where s_id in(
select s_id from Score 
GROUP BY s_id HAVING count(s_score) = (select count(c_id) from Course)
)

46、

-- 46、查询各学生的年龄
-- DATEDIFF函数:返回两个日期之间的天数  参数1 减去参数2
-- round 函数 取整  会进位  向上取整
-- 如果不进位可以使用 floor函数 向下取整
select s_id,s_birth,ROUND(DATEDIFF('2022-3.16',s_birth) / 365)
from Student

47、

-- 47、查询没学过“张三”老师讲授的任一门课程的学生姓名
select * from Student where s_id not in (
select s_id from  Score as sc 
INNER JOIN Course as co on sc.c_id = co.c_id
INNER JOIN Teacher as te on co.t_id = te.t_id
where te.t_name = '张三')

48、

-- 48、查询本月过生日的同学

select * from Student
WHERE MONTH(s_birth) = month(NOW())

49、

-- 49、查询下月过生日的学生

50


环境

/*
 Navicat Premium Data Transfer

 Source Server         : ssmbuild
 Source Server Type    : MySQL
 Source Server Version : 50716
 Source Host           : localhost:3306
 Source Schema         : sqldemo1

 Target Server Type    : MySQL
 Target Server Version : 50716
 File Encoding         : 65001

 Date: 17/03/2022 22:20:30
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `Cno` varchar(10) NOT NULL,
  `Cname` varchar(10) DEFAULT NULL,
  `Tno` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`Cno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of course
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');
COMMIT;

-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
  `Sno` varchar(10) NOT NULL,
  `Cno` varchar(10) NOT NULL,
  `score` decimal(18,1) DEFAULT NULL,
  PRIMARY KEY (`Sno`,`Cno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of sc
-- ----------------------------
BEGIN;
INSERT INTO `sc` VALUES ('01', '01', 80.0);
INSERT INTO `sc` VALUES ('01', '02', 90.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', 80.0);
INSERT INTO `sc` VALUES ('03', '02', 80.0);
INSERT INTO `sc` VALUES ('03', '03', 80.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);
COMMIT;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `Sno` varchar(10) NOT NULL,
  `Sname` varchar(10) DEFAULT NULL,
  `Sage` date DEFAULT NULL,
  `Ssex` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`Sno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01', '男');
INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21', '男');
INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20', '男');
INSERT INTO `student` VALUES ('04', '李云', '1990-08-06', '男');
INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01', '女');
INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01', '女');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01', '女');
INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20', '女');
INSERT INTO `student` VALUES ('09', '王菊', '2022-03-16', '女');
COMMIT;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `Tno` varchar(10) NOT NULL,
  `Tname` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`Tno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of teacher
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES ('01', '张三');
INSERT INTO `teacher` VALUES ('02', '李四');
INSERT INTO `teacher` VALUES ('03', '王五');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

1、Like

-- 查询「李」姓老师的数量 【Like】
select count(Tno) from teacher where Tname like "李%"

2、

-- 2. 查询名字中含有「风」字的学生信息【Like】

select * from student
where Sname like "%风%"

3、聚合函数

-- 3. 查询男生、女生人数【聚合函数】

select Ssex,count(*) from student
GROUP BY Ssex

4、

-- 4. 查询课程编号为02的总成绩【聚合函数】

select sum(score) from sc
where Cno = '02'

select cno, sum(score) from sc 
group by cno having cno='02';

5、

-- 5. 查询每门课程的平均成绩,结果按平均成绩降序排列,
-- 平均成绩相同时,按课程编号升序排列【聚合函数】

select cno,avg(score) from sc
GROUP BY cno
order by avg(score) desc,cno asc

6、

-- 6. 求每门课程的学生人数 【聚合函数】

select cno,count(sno) from sc
GROUP BY Cno

7、

-- 7. 统计每门课程的学生选修人数(超过 5 人的课程才统计)【聚合函数】

select cno,count(score) from sc
group by Cno HAVING count(score) > 5
order by count(score) desc,cno asc

8、

-- 8. 检索至少选修两门课程的学生学号 【聚合函数】

select sno,count(score) from sc 
GROUP BY sno HAVING count(score) >= 2

9、子查询

-- 9. 查询在 SC 表存在成绩的学生信息【子查询】

select * from student
where sno in (
select sno from sc
)

10、

-- 10. 查询不存在" 01 "课程但存在" 02 "课程的情况【子查询】

select * from sc
where sno not in (select sno from sc where cno =01)
and sno in (select sno from sc where cno=02);

11、

-- 11. 查询同时存在" 01 "课程和" 02 "课程的情况【子查询】

select * from sc where 
sno in (
select sno from sc where cno = '01'
) and sno in (select sno from sc where cno = '02')

12、

-- 12. 查询出只选修两门课程的学生学号和姓名【子查询】
select Sno,Sname from student
where sno in(
select sno from sc 
group by sno HAVING count(cno) = 2
)

13、

-- 13. 查询没有学全所有课程的同学的信息 【子查询】
select * from student
where sno not in (
select sno from sc
GROUP BY sno HAVING count(cno) = (
select count(Cno) from course
)
)

--  错误答案 因为sc没有 08号学生
select * from student
where sno  in (
select sno from sc
GROUP BY sno HAVING count(cno) < (
select count(Cno) from course
)
)

14、

-- 14. 查询选修了全部课程的学生信息【子查询】
select * from student
where sno in (
select sno from sc 
GROUP BY Sno having count(cno) = (select count(cno) from course)
)

15、

-- 15. 查询所有课程成绩均小于60分的学号、姓名【子查询】
select * from student
where sno not in (
select sno from sc
where score >= 60
) and sno in (select DISTINCT sno FROM sc)

16、

-- 16. 查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名【子查询】

select sno, sname from student
where sno in (select sno from sc where cno='01' and score>80);

17、

-- 17. 查询学过「张三」老师授课的同学的信息 【子查询】
select * from student
where sno in (
select sno from sc
where cno in (
select cno from course where cno = (
select tno from teacher where Tname = '张三'
)
)
)

18、

-- 18. 查询没学过"张三"老师讲授的任一门课程的学生姓名 【子查询】
select * from student where sno not in (
select sno from sc where cno in (
select course.cno from course,teacher
where course.Tno = teacher.Tno and teacher.Tname = '张三'
))


select * from student where sno not in (
select sc.sno from sc,course,teacher
where sc.Cno = course.Cno and teacher.Tno = course.Tno and teacher.Tname = '张三'
)

19、

-- 19. 查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息 【子查询】
select * from student where sno in (
select sno from sc where cno in (
select cno from sc where sno = 01
) and sno != '01'
GROUP BY sno
)

20、

-- 20. 查询和" 01 "号的同学学习的课程完全相同的其他同学的信息【子查询】
select * from student where sno  in (
select sno from sc 
where sno != 01
GROUP BY sno HAVING count(Cno) = (select count(cno) from sc where sno = 01)
) 
and sno not in (
select sno from sc 
where Cno not in (select cno from sc where sno = 01)
)

21、

-- 21. 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 【子查询】

select * from sc where sno in 
(select sno from sc group by sno
having min(score)=max(score) and count(*)>1);




22、联表查询

-- 22. 检索" 01 "课程分数小于 60,按分数降序排列的学生信息【inner join】

select b.*, a.score 
from sc as a inner join student as b on a.sno=b.sno
where a.cno='01' and a.score<60 order by a.score desc;

select a.*,b.score from student as a
INNER JOIN (
select sno,score from sc where cno = 01 and score < 60
) as b on a.sno = b.sno

23、

-- 23. 查询不及格的课程及学生名,学号,按课程号从大到小排列【inner join】
select st.Sno,st.Sname,sc.cno,sc.score from student as st
INNER JOIN  sc
on st.sno = sc.sno
where sc.score < 60
order by cno desc


24、

-- 24. 查询课程名称为「数学」,且分数低于 60 的学生姓名和分数 【inner join】
select st.Sname,c.Cname,sc.score from student as st
INNER JOIN sc on st.sno = sc.sno
INNER JOIN course as c on sc.cno = c.Cno
where c.Cname = '数学' and sc.score < 60

select b.sname, a.score
from sc as a inner join student as b on a.sno=b.sno
where a.score<60 and a.cno =(select cno from course where cname='数学');

25、

-- 25. 查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩 【inner join】

select st.Sno,st.Sname,avg(score) from student as st
INNER JOIN sc on st.sno = sc.sno
group by sno HAVING avg(score) >= 85


26、

-- 26. 查询不同老师所教不同课程平均分从高到低显示【inner join】

select b.tno, a.cno, avg(a.score)
from sc as a inner join course as b on a.cno=b.cno
group  by a.cno order by avg(a.score) desc;

27、

-- 27. 查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩【inner join】

select st.Sno,st.Sname,avg(score) from student as st
INNER JOIN sc on st.sno = sc.Sno
group by sno HAVING avg(sc.score) >= 60

28、

-- 28.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩【inner join】

select st.Sno,st.Sname,avg(sc.score),count(sc.score) from student as st
INNER JOIN sc on st.sno = sc.sno
where sc.score < 60
GROUP BY sno HAVING count(score) >=2

29、

-- 29. 查询同名同性学生名单,并统计同名同性人数【inner join】

select a.*, b.student_number
from student as a inner join 
(select sname, ssex, count(*) as student_number from student 
group by sname, ssex having count(*)>1) as b
on a.sname=b.sname and a.ssex=b.ssex;


30、

-- 30. 查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)【outer join】

select a.sno, a.sname, b.cno, b.score
from student as a left join sc as b
on a.sno=b.sno;

31、

-- 31. 查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩。
-- (没成绩的显示为 null )【outer join】

select st.Sno,st.Sname,count(DISTINCT cno),sum(score) from student as st
LEFT JOIN sc on st.sno = sc.sno
GROUP BY sno 

32、

-- 32. 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )【outer join】

select a.*, b.cno, b.score from 
(select * from sc where cno='01') as a 
left join (select * from sc where cno='02') as b
on a.sno=b.sno;


33、

-- 33. 查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数【三表联结】

select st.Sname,co.Cname,sc.score from student as st
INNER JOIN sc on st.sno = sc.sno
INNER JOIN course as co on sc.cno = co.cno
where sc.score > 70



34、

-- 34. 查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数【三表联结】
select a.*,b.score from student as a
INNER JOIN (
select * from sc where cno = 01
) as b on a.sno = b.sno
INNER JOIN (
select * from sc where cno = 02
) as c on b.sno = c.sno
where b.score > c.score

35、limit

-- 35. 成绩不重复,查询选修「张三」老师所授课程的学生中,
-- 成绩最高的学生信息及其成绩【limit】
select st.*,g.score from student  as st
INNER JOIN 
(
select * from sc where 
sc.Cno = (
select c.cno from course as c
INNER JOIN 
(select tno from teacher where tname = '张三') as t 
on c.tno = t.Tno
)
ORDER BY score desc
limit 0,1
) as g on st.sno = g.sno


select student.*, sc.score
from sc, course, teacher,student
where teacher.tname='张三' and course.tno=teacher.tno and 
course.cno=sc.cno and student.sno=sc.sno
order by sc.score desc limit 1;

36、

-- 36. 成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩【limit】

select a.* from 
(select student.*, sc.cno, sc.score from student, sc where student.sno=sc.sno) as a
inner join
(select cno, score from sc where cno=(select cno from course, teacher where teacher.tname='张三' 
and course.tno=teacher.tno )order by score desc limit 1) as b
on a.cno=b.cno and a.score=b.score;


37、窗口函数

-- 37. 按各科成绩进行排序,并显示排名,Score 重复时保留名次空缺【窗口函数】
select *, rank() over (partition by cno order by score desc) as ranking
from sc;

38、

-- 38. 按各科成绩进行排序,并显示排名,Score 重复时合并名次【窗口函数】

39、

-- 39. 查询学生的总成绩,并进行排名,总分重复时保留名次空缺【窗口函数】

40、

-- 40. 查询学生的总成绩,并进行排名,总分重复时不保留名次空缺【窗口函数】

41、


42、


43、


44、case

-- 44.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩【case】

select sc.sno,
max(case when course.Cname = '语文'then sc.score else 0 end) as "语文",
max(case when course.Cname = '数学'then sc.score else 0 end) as "数学",
max(case when course.Cname = '英语'then sc.score else 0 end) as "英语",
avg(sc.score)
from sc
INNER JOIN course
on sc.cno = course.Cno
GROUP BY sc.Sno


select b.sno, a.avg_score, a.01, a.02, a.03 from 
(select sno, avg(score) as avg_score,
max(case when cno='01' then score else null end) as '01',
max(case when cno='02' then score else null end) as '02',
max(case when cno='03' then score else null end) as '03'
from sc group by sno) as a 
right join student as b on a.sno=b.sno;


45、

-- 45. 使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,
-- 分别统计各分数段人数:课程ID和课程名称【case】
select c.Cname,sc.cno ,
sum(case when sc.score > 85 and sc.score <= 100 then 1 else 0 end) as '[100-85)',
sum(case when sc.score > 70 and sc.score <= 85  then 1 else 0 end) as '[85-70)',
sum(case when sc.score > 60 and sc.score <= 70 then 1 else 0 end) as '[70-60)',
sum(case when sc.score <= 60 then 1 else 0 end) as '[<60)'
from course  as c
INNER JOIN sc on c.cno = sc.cno
GROUP BY cno


46、

-- 46. 查询各科成绩最高分、最低分和平均分:以如下形式显示:
-- 课程 ID ,课程 name ,最高分,最低分,平均分,及格率,中等率,优良率,优秀率。
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 【case】

select a.cno '课程ID', b.cname '课程name', max(a.score) '最高分', min(a.score) '最低分', avg(a.score) '平均分',
sum(case when a.score>=60 then 1 else 0 end)/count(a.score) '及格率',
sum(case when a.score>=70 and a.score<80 then 1 else 0 end)/count(a.score) '中等率',
sum(case when a.score>=80 and a.score<90 then 1 else 0 end)/count(a.score) '优良率',
sum(case when a.score>=90 then 1 else 0 end)/count(a.score) '优秀率'
from sc a inner join course b on a.cno=b.cno
group by a.cno;

47、

-- 47. 统计各科成绩各分数段人数:
-- 课程编号,课程名称,[100-85],[85-70],[70-60],[60-0] 及所占百分比【case】
select a.cno, b.cname, 
sum(case when a.score>=85 then 1 else 0 end) as '[100-85]人数',
sum(case when a.score>=70 and a.score<85 then 1 else 0 end) as '[85-70]人数',
sum(case when a.score>=60 and a.score<70 then 1 else 0 end) as '[70-60]人数',
sum(case when a.score<60 then 1 else 0 end) as '[60-0]人数',
sum(case when a.score>=85 then 1 else 0 end)/count(a.sno) as '[100-85]百分比',
sum(case when a.score>=70 and a.score<85 then 1 else 0 end)/count(a.sno) as '[85-70]百分比',
sum(case when a.score>=60 and a.score<70 then 1 else 0 end)/count(a.sno) as '[70-60]百分比',
sum(case when a.score<60 then 1 else 0 end)/count(a.sno) as '[60-0]百分比'
from sc as a inner join course as b on a.cno=b.cno
group by a.cno;

48、时间函数

-- 48. 查询各学生的年龄,只按年份来算【时间函数】

-- 思路:year函数分别求出current_date和sage的年,相减即可
select sno, sname, 
year(current_date())-year(sage) as age
from student;

49、

-- 49. 按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一【时间函数】
-- 思路:使用timestampdiff()求差,将时间戳设置为年即可
Select sno, sname,
timestampdiff(year, sage, current_date()) as age
from student;

50、

-- 50. 查询本月过生日的学生【时间函数】
-- 思路:month函数分别求出current_date和sage的月份,相同即可
select sno, sname, sage from student 
where month(sage)=month(current_date());

51、

-- 51. 查询下月过生日的学生
-- 思路参见50
select sno, sname, sage from student 
where month(sage)=month(current_date())+1;

52、

-- 52. 查询本周过生日的学生
/* 思路:1.replace将生日中的年换为今天的年,计算同学的生日在本年是第几周;
               2.求出今天是本年的第几周 
               3.若相等,则符合条件 
注意:这种方法存在问题,1月第一周和12月最后一周可能跨年,倒置结果出错。欢迎提供更好的方案。*/
select sno, sname, sage from student 
where week(replace(sage, year(sage), year(current_date())), 1) = week(current_date(),1);

53、

-- 53. 查询下周过生日的学生
-- 思路和存在问题参见52
select sno, sname, sage from student 
where week(replace(sage, year(sage), year(current_date())), 1) = week(current_date(),1)+1;
举报

相关推荐

0 条评论