表及数据
1表 学生表
create table student(
s_id int,
s_name string,
dt string,
sex string
)
row format delimited
fields terminated by '\t';
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 女
2表 课程表
create table course(
c_id string,
c_name string,
t_id string
)
row format delimited
fields terminated by '\t';
01 语文 02
02 数学 01
03 英语 03
3表 教师表
create table teacher(
t_id string,
t_name string
)
row format delimited
fields terminated by '\t';
01 张三
02 李四
03 王五
4表 成绩表
create table score(
s_id string,
c_id string,
score int
)
row format delimited
fields terminated by '\t';
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
1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数。
思路:1、查询01数学成绩
select s_id,score from score where c_id='01'; t1
2、查询02语文成绩
select s_id,score from score where c_id='02'; t2
3、查询数学01比语文02成绩高的人的id、语文成绩、数学成绩
select t1.s_id t1s_id,t1.score math,t2.score chinese
from t1 join t2 on t1.s_id=t2.s_id
where t1.score>t2.score; t3
4、查询数学01比语文02成绩高的人的id、数学成绩、语文成绩及学生的信息。
select t1s_id,math,chinese,s_name,dt,sex from t3
left join student s1 on t3.t1s_id=s1.s_id;
最终SQL
select t1s_id,math,chinese,s_name,dt,sex
from (select t1.s_id t1s_id,t1.score math,t2.score chinese
from (select s_id,score from score where c_id='01')t1
join (select s_id,score from score where c_id='02')t2 on t1.s_id=t2.s_id
where t1.score>t2.score)t3
left join student s1 on t3.t1s_id=s1.s_id;
2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
思路:同1,仅仅改变大于号小于号
最终SQL
select t1s_id,math,chinese,s_name,dt,sex
from (select t1.s_id t1s_id,t1.score math,t2.score chinese
from (select s_id,score from score where c_id='01')t1
join (select s_id,score from score where c_id='02')t2 on t1.s_id=t2.s_id
where t1.score<t2.score)t3
left join student s1 on t3.t1s_id=s1.s_id;
3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
思路:1、所有同学的编号及平均成绩
select s_id,avg(score) avg_score from score group by s_id;t1
2、平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select t1.s_id,s1.s_name,floor(t1.avg_score) avg_score
from t1 left join student s1 on t1.s_id=s1.s_id
where avg_score>=60;
最终SQL
select t1.s_id,s1.s_name,floor(t1.avg_score) avg_score
from (select s_id,avg(score) avg_score from score group by s_id)t1
left join student s1 on t1.s_id=s1.s_id
where avg_score>=60;
4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩(包括有成绩的和无成绩的)
5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
思路:1、查询所有同学的编号,姓名
select s_id,s_name from student;t1
2、所有同学的选课总数,课程总成绩
select s_id,count(c_id) count_course,sum(score) count_score from score
group by s_id;t2
3、所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select t1.s_id,t1.s_name,t2.count_course,t2.count_score from t1
left join t2 on t1.s_id=t3.s_id;
最终SQL
select t1.s_id,t1.s_name,t2.count_course,t2.count_score
from (select s_id,s_name from student)t1
left join (select s_id,count(c_id) count_course,sum(score) count_score from score
group by s_id)t2
on t1.s_id=t2.s_id;
6、查询"李"姓老师的数量
select count(t_name) count_li_teacher from teacher where t_name like '李%';
7、查询学过"张三"老师授课的同学的信息
思路:1、从教师表中查询张三的教师编号
select t_id from teacher where t_name='张三';t1
2、从课程表里找到张三教的课程编号
select t1.t_id t1_t_id,c1.c_id c1_c_id
from t1
left join course c1 on t1.t_id=c1.t_id;t2
3、从成绩表中找到课程编号所对应的学生编号
select t2.c1_c_id t2_t1_c_id,sc.s_id sc_s_id
from t2
left join score sc on t2.c1_c_id=sc.c_id;t3
4、从学生表根据学生编号找出学生信息
select t3.sc_s_id,st.s_name,st.s_dt,st.s_sex
from t3
left join student st on t3.sc_s_id=st.s_id;
最终SQL
select t3.sc_s_id,st.s_name,st.dt,st.sex
from (select t2.c1_c_id t2_t1_c_id,sc.s_id sc_s_id
from (select t1.t_id t1_t_id,c1.c_id c1_c_id
from (select t_id from teacher where t_name='张三')t1
left join course c1 on t1.t_id=c1.t_id)t2
left join score sc on t2.c1_c_id=sc.c_id)t3
left join student st on t3.sc_s_id=st.s_id;
8、查询没学过"张三"老师授课的同学的信息
思路:1、从教师表中查询非张三的所有教师编号
select t_id from teacher where t_name not like '张三';t1
2、从课程表里找到非张三教的课程编号
select t1.t_id t1_t_id,c1.c_id c1_c_id
from t1 left join course c1 on t1.t_id=c1.t_id;t2
3、从成绩表中找到课程编号所对应的学生编号
select distinct(sc.s_id) sc_s_id
from t2 left join score sc on t2.c1_c_id=sc.c_id;t3
4、从学生表根据学生编号找出学生信息
select t3.sc_s_id,st.s_name,st.dt,st.sex
from t3 left join student st on t3.sc_s_id=st.s_id;
最终SQL
select t3.sc_s_id,st.s_name,st.dt,st.sex
from (select distinct(sc.s_id) sc_s_id
from (select t1.t_id t1_t_id,c1.c_id c1_c_id
from (select t_id from teacher where t_name not like '张三')t1
left join course c1 on t1.t_id=c1.t_id)t2
left join score sc on t2.c1_c_id=sc.c_id)t3
left join student st on t3.sc_s_id=st.s_id;
9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
思路:1、学过编号01的
select s_id 01_s_id from score where c_id='01'; t1
2、学过编号02的
select s_id 02_s_id from score where c_id='02'; t2
3、学过编号为"01"并且也学过编号为"02"
select 01_s_id 01_02_s_id
from t1 join t2 on t1.01_s_id=t2.02_s_id;t3
4、学过编号为"01"并且也学过编号为"02"的课程的同学的信息
select 01_02_s_id,s1.s_name,s1.dt,s1.sex
from t3
left join student s1
on t3.01_02_s_id=s1.s_id;
最终SQL
select 01_02_s_id,s1.s_name,s1.dt,s1.sex
from (select 01_s_id 01_02_s_id
from (select s_id 01_s_id
from score where c_id='01')t1
join (select s_id 02_s_id
from score where c_id='02')t2 on t1.01_s_id=t2.02_s_id)t3
left join student s1
on t3.01_02_s_id=s1.s_id;
10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
思路:1、学过编号01的
select s_id from score where c_id='01'; t1
2、学过编号02的
select s_id from score where c_id='02'; t2
3、学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
select *
from t1
left join
student s1 on t1.s_id=s1.s_id
left join t2
on s1.s_id=t2.s_id
where t2.s_id is null;
最终SQL
select *
from (select s_id
from score where c_id='01')t1
left join
student s1 on t1.s_id=s1.s_id
left join (select s_id
from score where c_id='02')t2
on s1.s_id=t2.s_id
where t2.s_id is null;
11、查询没有学全所有课程的同学的信息
思路:1、查出所有课程总数
select count(c_id) count_t1_c_id from course;t1
2、查出所有同学学习的课程总数
select s_id,count(c_id) count_c_id from score group by s_id;t2
3、查出没有学全所有课程的同学的编号
select t2.s_id s_id
from t2 join t1
where t2.count_c_id < t1.count_t1_c_id;t3
4、查询没有学全所有课程的同学的信息
select t3.s_id,s1.s_name,s1.dt,s1.sex
from t3 left join student s1 on t3.s_id = s1.s_id;
最终SQL
select t3.s_id,s1.s_name,s1.dt,s1.sex
from (select t2.s_id s_id
from (select s_id,count(c_id) count_c_id
from score group by s_id)t2
join (select count(c_id) count_t1_c_id
from course)t1
where t2.count_c_id < t1.count_t1_c_id)t3
left join student s1 on t3.s_id = s1.s_id;
此sql跑了6个job,应该会有更优化的查询。
12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息
注意点:------------------in中不允许有子查询---------------------
思路:1、学号01同学所学的课程号
select c_id from score where s_id='01';t1
2、至少有一门课与学号为"01"的同学所学相同的同学id
select s1.s_id s1_s_id
from score s1 where s1.c_id in t1 group by s1.s_id;t2
3、至少有一门课与学号为"01"的同学所学相同的同学的信息
select s1_s_id,st.s_name,st.dt,st.sex
from t2 left join student st on t2.s1_s_id=st.s_id;
最终SQL
select s1_s_id,st.s_name,st.dt,st.sex
from (select s1.s_id s1_s_id
from score s1
where s1.c_id
in (select c_id from score where s_id='01') group by s1.s_id)t2
left join student st on t2.s1_s_id=st.s_id;
有个不好,连01同学也查出来了
13、查询和"01"号的同学学习的课程完全相同的其他同学的信息
思路:1、01同学的所选课程以及课程数
select c_id,count(*) over(partition by s_id) sum_01_c_id
from score where s_id='01';t1
2、除01同学外所有同学的学号,课程号,课程总数
select s_id,c_id,count(c_id) over(partition by s_id) sum_c_id
from score where s_id!='01';t2
3、与01所学课程相同的学生id
select s_id
from t1
left join t2 on t1.c_id=t2.c_id
where t2.sum_c_id=t1.sum_01_c_id
group by s_id;t3
4、查询和"01"号的同学学习的课程完全相同的其他同学的信息
select t3.s_id,st.s_name,st.dt,st.sex
from t3
left join student st on t3.s_id=st.s_id;
最终SQL
select t3.s_id,st.s_name,st.dt,st.sex
from (select s_id
from (select c_id,count(*) over(partition by s_id) sum_01_c_id
from score where s_id='01')t1
left join (select s_id,c_id,count(c_id) over(partition by s_id) sum_c_id
from score where s_id!='01')t2 on t1.c_id=t2.c_id
where t2.sum_c_id=t1.sum_01_c_id
group by s_id)t3
left join student st on t3.s_id=st.s_id;
16、检索"01"课程分数小于60,按分数降序排列的学生信息
1、查看01课程分数小于60的人的学号
select s_id,score from score where c_id=01 and score<60 order by score desc; t1
2、查看01课程分数小于60的人的信息
select t1.s_id,t1.score,st.s_name,st.dt,st.sex
from t1 left join student st on t1.s_id=st.s_id;
最终SQL
select t1.s_id,t1.score,st.s_name,st.dt,st.sex
from (select s_id,score from score
where c_id=01 and score<60 order by score desc)t1
left join student st on t1.s_id=st.s_id;
20、查询学生的总成绩并进行排名
1、查询总成绩的排名及学生编号
select s_id,sum(score) sum_score from score
group by s_id order by sum_score desc; t1
2、学生的总成绩并进行排名
select t1.s_id,st.s_name,t1.sum_score
from (select s_id,sum(score) sum_score
from score group by s_id order by sum_score desc)t1
join student st on t1.s_id=st.s_id;