后面25题: https://blog.csdn.net/qq_35954433/article/details/85276223
create table if not exists t_stu_info(
stu_id int,
stu_name string,
birthday string,
gender string
)
row format delimited
fields terminated by ' ';
load data local inpath '/home/testdata/stu_info.txt' into table t_stu_info;
01 赵雷 1990-01-01 男
02 钱电 1990-12-21 男
03 孙风 1990-05-20 男
04 李云 1990-08-06 男
05 周梅 1991-12-01 女
06 吴兰 1992-03-01 女
07 郑竹 1989-07-01 女
08 王菊 1990-01-20 女
注!以下两条数据为第30题查询同名同性学生时添加,即前29题的操作数据只有前面8条,
后面的21题产生数据结果才会受到以下两条数据的影响
09 郑竹 1989-07-02 女
10 王菊 1990-02-09 女
create table if not exists t_course(
stu_id int,
course string,
teach_id int
)
row format delimited
fields terminated by '\t';
load data local inpath '/home/testdata/course.txt' into table t_course;
01 语文 02
02 数学 01
03 英语 03
create table if not exists t_teach(
teach_id int,
teach_name string
)
row format delimited
fields terminated by '\t';
load data local inpath '/home/testdata/teach_info.txt' into table t_teach;
01 张三
02 李四
03 王五
create table if not exists t_score(
stu_id int,
course_id int,
score int
)
row format delimited
fields terminated by '\t';
load data local inpath '/home/testdata/score.txt' into table t_score;
01 01 80
01 02 90
01 03 99
02 01 70
02 02 60
02 03 80
03 01 80
03 02 80
03 03 80
04 01 50
04 02 30
04 03 20
05 01 76
05 02 87
06 01 31
06 03 34
07 02 89
07 03 98.
load表数据时可根据自己的实际数据路径进行导入
1、 查询"01"课程比"02"课程成绩高的学生的信息及课程分数:
select stu.*,sc.score,a.score
from t_stu_info stu
join t_score sc on sc.course_id = '01' and sc.stu_id = stu.stu_id
left join t_score a on a.course_id = '02' and a.stu_id = stu.stu_id
join t_score b on b.stu_id = stu.stu_id
where sc.score > a.score or a.score is null
group by stu.stu_id,stu.stu_name,stu.birthday,stu.gender,sc.score,a.score
;
运行结果(02课程未考试也算作低于01课程):
2 钱电 1990-12-21 男 70 60
4 李云 1990-08-06 男 50 30
6 吴兰 1992-03-01 女 31 NULL
2、 查询"01"课程比"02"课程成绩低的学生的信息及课程分数:
select stu.*,sc.score,a.score
from t_stu_info stu
full outer join t_score sc on sc.course_id = '01' and sc.stu_id = stu.stu_id
left join t_score a on a.course_id = '02' and a.stu_id = stu.stu_id
join t_score b on b.stu_id = stu.stu_id
where sc.score < a.score or sc.score is null
group by stu.stu_id,stu.stu_name,stu.birthday,stu.gender,sc.score,a.score
;
运行结果:
1 赵雷 1990-01-01 男 80 90
5 周梅 1991-12-01 女 76 87
7 郑竹 1989-07-01 女 NULL 89
3、 查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩:
select
stu.stu_id,
stu.stu_name,
round(avg(sc.score),2) as avgscore
from t_stu_info stu
join t_score sc on sc.stu_id = stu.stu_id
group by stu.stu_id,stu.stu_name
having round(avg(sc.score),2) >=60
;
运行结果:
1 赵雷 89.67
2 钱电 70.0
3 孙风 80.0
5 周梅 81.5
7 郑竹 93.5
4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩:
(包括有成绩的和无成绩的)
select
stu.stu_id,
stu.stu_name,
round(avg(sc.score),2) as avgscore
from t_stu_info stu
join t_score sc on sc.stu_id = stu.stu_id
group by stu.stu_id,stu.stu_name
having round(avg(sc.score),2) < 60
union all
select
stu.stu_id,
stu.stu_name,
0 as avgscore
from t_stu_info stu
left join t_score sc on sc.stu_id = stu.stu_id
where sc.score is null
;
运行结果:
8 王菊 0.0
4 李云 33.33
6 吴兰 32.5
5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩:
select a.stu_id,a.stu_name,count(a.stu_id),sum(b.score)
from t_stu_info a left join t_score b on a.stu_id=b.stu_id
group by a.stu_id,a.stu_name;
运行结果:
1 赵雷 3 269
2 钱电 3 210
3 孙风 3 240
4 李云 3 100
5 周梅 2 163
6 吴兰 2 65
7 郑竹 2 187
8 王菊 1 NULL
6、查询"李"姓老师的数量:
select teach_name,count(*)
from
t_teach
where teach_name like '李%'
group by teach_name;
运行结果:
李四 1
7、查询学过"张三"老师授课的同学的信息:
答案一:
select a.stu_id,a.stu_name ,a.birthday,a.gender,d.teach_name
from
t_stu_info a
join t_teach d on d.teach_name='张三'
join t_course c on c.teach_id=d.teach_id
join t_score b on a.stu_id=b.stu_id and b.course_id=c.course_id
运行结果:
1 赵雷 1990-01-01 男 张三
2 钱电 1990-12-21 男 张三
3 孙风 1990-05-20 男 张三
4 李云 1990-08-06 男 张三
5 周梅 1991-12-01 女 张三
7 郑竹 1989-07-01 女 张三
答案二(left semi join):
from t_stu_info stu
join t_teach ter on ter.teach_name = '张三'
join t_course cs on ter.teach_id = cs.teach_id
left semi join t_score sc on sc.stu_id = stu.stu_id and sc.course_id = cs.course_id
;
运行结果:
1 赵雷 1990-01-01 男
2 钱电 1990-12-21 男
3 孙风 1990-05-20 男
4 李云 1990-08-06 男
5 周梅 1991-12-01 女
7 郑竹 1989-07-01 女
8、查询没学过"张三"老师授课的同学的信息:
select stu.*,cs.course_id,sc.score
from t_stu_info stu
join t_teach ter on ter.teach_name = '张三'
join t_course cs on ter.teach_id = cs.teach_id
left join t_score sc on sc.stu_id = stu.stu_id and sc.course_id = cs.course_id
where sc.score is null
;
运行结果:
6 吴兰 1992-03-01 女 2 NULL
8 王菊 1990-01-20 女 2 NULL
9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息:
答案一:
select a.stu_id,a.stu_name,a.birthday,a.gender,count(a.stu_id)
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id
where b.course_id in(1,2)
group by a.stu_id,a.stu_id,a.stu_name,a.birthday,a.gender
having count(a.stu_id)>1;
运行结果:
1 赵雷 1990-01-01 男 2
2 钱电 1990-12-21 男 2
3 孙风 1990-05-20 男 2
4 李云 1990-08-06 男 2
5 周梅 1991-12-01 女 2
答案二:
select stu.stu_id,stu.stu_name
from t_stu_info stu
join t_score sc on sc.course_id= '01' and sc.stu_id = stu.stu_id
join t_score sc1 on sc1.course_id= '02' and sc1.stu_id = sc.stu_id
;
运行结果:
1 赵雷
2 钱电
3 孙风
4 李云
5 周梅
10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息:
select stu.stu_id,stu.stu_name
from t_stu_info stu
join t_score sc on sc.course_id= '01' and sc.stu_id = stu.stu_id
left join t_score sc1 on sc1.course_id= '02' and sc1.stu_id = sc.stu_id
where sc1.score is null
;
运行结果:
6 吴兰
11、查询没有学全所有课程的同学的信息:
–先查询出课程的总数量–再查询所需结果
select distinct stu.stu_id,stu.stu_name
from t_stu_info stu
join t_course cs
left join t_score sc on sc.stu_id = stu.stu_id and cs.course_id = sc.course_id
where sc.score is null
;
运行结果:
5 周梅
6 吴兰
7 郑竹
8 王菊
12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息:
select distinct stu.stu_id,stu.stu_name
from t_stu_info stu
join t_score sc on sc.stu_id = '01'
left join t_score sc1 on sc1.stu_id = stu.stu_id and sc1.course_id = sc.course_id
where stu.stu_id <> '01' and sc1.score is not null
;
运行结果:
2 钱电
3 孙风
4 李云
5 周梅
6 吴兰
7 郑竹
13、查询和"01"号的同学学习的课程完全相同的其他同学的信息:
select *
from
(
select
a.stu_id,
concat_ws(",",collect_set(cast(a.course_id as string))) as course1
from t_score a
where a.stu_id='1'
group by a.stu_id
) b join
(
select
c.stu_id,
concat_ws(",",collect_set(cast(c.course_id as string))) as course2
from t_score c
group by c.stu_id
) d on b.course1=d.course2 and d.stu_id<>'1'
;
运行结果:
1 1,2,3 2 1,2,3
1 1,2,3 3 1,2,3
1 1,2,3 4 1,2,3
14、查询没学过"张三"老师讲授的任一门课程的学生姓名:
select a.*,sum(d.teach_name)
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id
left join t_course c on c.course_id=b.course_id
left join t_teach d on c.teach_id=d.teach_id and d.teach_name='张三'
group by a.stu_id,a.stu_name,a.birthday,a.gender
having sum(case when d.teach_name is null then 0 else 1 end)=0
;
运行结果:
6 吴兰 1992-03-01 女 NULL
8 王菊 1990-01-20 女 NULL
15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩:
select a.stu_id,a.stu_name,round(avg(b.score),2)
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id
where b.score<60
group by a.stu_id,a.stu_name
having count(a.stu_id)>1;
运行结果:
4 李云 33.33
6 吴兰 32.5
16、检索"01"课程分数小于60,按分数降序排列的学生信息:
select a.*,b.score
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id and b.course_id='1'
where b.score<60
order by b.score desc
;
运行结果:
4 李云 1990-08-06 男 50
6 吴兰 1992-03-01 女 31
17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩:
select a.*,b.course_id,b.score,
round(avg(b.score) over(partition by a.stu_id order by b.score desc rows between unbounded preceding and unbounded following),2) as avg
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id
order by avg desc
;
运行结果:
7 郑竹 1989-07-01 女 2 89 93.5
7 郑竹 1989-07-01 女 3 98 93.5
1 赵雷 1990-01-01 男 3 99 89.67
1 赵雷 1990-01-01 男 2 90 89.67
1 赵雷 1990-01-01 男 1 80 89.67
5 周梅 1991-12-01 女 1 76 81.5
5 周梅 1991-12-01 女 2 87 81.5
3 孙风 1990-05-20 男 1 80 80.0
3 孙风 1990-05-20 男 3 80 80.0
3 孙风 1990-05-20 男 2 80 80.0
2 钱电 1990-12-21 男 2 60 70.0
2 钱电 1990-12-21 男 3 80 70.0
2 钱电 1990-12-21 男 1 70 70.0
4 李云 1990-08-06 男 1 50 33.33
4 李云 1990-08-06 男 3 20 33.33
4 李云 1990-08-06 男 2 30 33.33
6 吴兰 1992-03-01 女 3 34 32.5
6 吴兰 1992-03-01 女 1 31 32.5
8 王菊 1990-01-20 女 NULL NULL NULL
18.查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率:
select a.course_id,b.course,
round(max(a.score),2) as maxV,
round(min(a.score),2) as minV,
round(avg(a.score),2) as avgV,
round(sum(case when a.score<60 then 1 else 0 end)/count(1),2) as fail,
round(sum(case when a.score>60 and a.score<=70 then 1 else 0 end)/count(1),2) as pass,
round(sum(case when a.score>70 and a.score<=80 then 1 else 0 end)/count(1),2) as middle,
round(sum(case when a.score>80 and a.score<=90 then 1 else 0 end)/count(1),2) as good,
round(sum(case when a.score>90 and a.score<=100 then 1 else 0 end)/count(1),2) as excellent
from
t_score a left join t_course b on a.course_id=b.course_id
group by a.course_id,b.course
;
运行结果:
1 语文 80 31 64.5 0.33 0.17 0.5 0.0 0.0
2 数学 90 30 72.67 0.17 0.0 0.17 0.5 0.0
3 英语 99 20 68.5 0.33 0.0 0.33 0.0 0.33
19、按各科成绩进行排序,并显示排名:– row_number() over()分组排序功能
select course_id,score,
row_number() over(partition by course_id order by score)
from
t_score
;
运行结果:
1 31 1
1 50 2
1 70 3
1 76 4
1 80 5
1 80 6
2 30 1
2 60 2
2 80 3
2 87 4
2 89 5
2 90 6
3 20 1
3 34 2
3 80 3
3 80 4
3 98 5
3 99 6
20、查询学生的总成绩并进行排名:
select a.stu_name,
sum(b.score) as total
from
t_stu_info a left join t_score b on a.stu_id=b.stu_id
group by a.stu_name
order by total desc
;
运行结果:
赵雷 269
孙风 240
钱电 210
郑竹 187
周梅 163
李云 100
吴兰 65
王菊 NULL
21、查询不同老师所教不同课程平均分从高到低显示:
select a.teach_name,round(avg(c.score),2)as avg
from
t_teach a left join t_course b on a.teach_id=b.teach_id
left join t_score c on b.course_id=c.course_id
group by a.teach_name
order by avg desc
;
运行结果:
张三 72.67
王五 68.5
李四 64.5
22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩:
select a.stu_id,a.course_id,b.stu_name,b.birthday,b.gender,a.score,a.rank
from
(
select stu_id,course_id,score,
row_number() over(partition by course_id order by score) as rank
from
t_score
) a join t_stu_info b on a.stu_id=b.stu_id
where a.rank in('2','3')
;
运行结果:
4 1 李云 1990-08-06 男 50 2
2 1 钱电 1990-12-21 男 70 3
2 2 钱电 1990-12-21 男 60 2
3 2 孙风 1990-05-20 男 80 3
6 3 吴兰 1992-03-01 女 34 2
3 3 孙风 1990-05-20 男 80 3
23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select a.course_id,b.course,
sum(case when a.score<60 then 1 else 0 end) as fail,
sum(case when a.score>60 and a.score<=70 then 1 else 0 end) as pass,
sum(case when a.score>70 and a.score<=85 then 1 else 0 end) as good,
sum(case when a.score>85 and a.score<=100 then 1 else 0 end)as excellent,
round(sum(case when a.score<60 then 1 else 0 end)/count(1),2),
round(sum(case when a.score>60 and a.score<=70 then 1 else 0 end)/count(1),2),
round(sum(case when a.score>70 and a.score<=85 then 1 else 0 end)/count(1),2),
round(sum(case when a.score>85 and a.score<=100 then 1 else 0 end)/count(1),2)
from
t_score a left join t_course b on a.course_id=b.course_id
group by a.course_id,b.course
;
运行结果:
1 语文 2 1 3 0 0.33 0.17 0.5 0.0
2 数学 1 0 1 3 0.17 0.0 0.17 0.5
3 英语 2 0 2 2 0.33 0.0 0.33 0.33
24、查询学生平均成绩及其名次:
select a.stu_id,a.avg,
row_number() over(order by avg desc)
from
(
select stu_id,
round(avg(score),2) as avg
from
t_score
group by stu_id
) a
;
运行结果:
7 93.5 1
1 89.67 2
5 81.5 3
3 80.0 4
2 70.0 5
4 33.33 6
6 32.5 7
25、查询各科成绩前三名的记录三个语句
select a.stu_id,a.course_id,a.score,a.rn,a.rk,a.dk
from
(
select *,
row_number() over(partition by stu_id order by score) as rn,
rank() over(partition by stu_id order by score) as rk,
dense_rank() over(partition by stu_id order by score) as dk
from
t_score
) a
where a.rn<4 and a.rk<4 and a.dk<4
;
运行结果:
1 1 80 1 1 1
1 2 90 2 2 2
1 3 99 3 3 3
2 2 60 1 1 1
2 1 70 2 2 2
2 3 80 3 3 3
3 3 80 1 1 1
3 2 80 2 1 1
3 1 80 3 1 1
4 3 20 1 1 1
4 2 30 2 2 2
4 1 50 3 3 3
5 1 76 1 1 1
5 2 87 2 2 2
6 1 31 1 1 1
6 3 34 2 2 2
7 2 89 1 1 1
7 3 98 2 2 2