5.1.5 查询出每门课程的及格人数和不及格人数
hive>
select c.course_id, c.course_name, t1.`及格人数`, t1.`不及格人数` from course_info c join ( select course_id, sum(if(score >= 60,1,0)) as `及格人数`, sum(if(score < 60,1,0)) as `不及格人数` from score_info group by course_id ) t1 on c.course_id = t1.course_id;
骚戴理解:这里注意`及格人数`的符号问题,是 ` 不是单引号‘
结果
c.course_id c.course_name t1.及格人数 t1.不及格人数
01 语文 12 7
02 数学 8 11
03 英语 13 6
04 体育 6 6
05 音乐 4 1
5.1.6 查询课程编号为03且课程成绩在80分以上的学生的学号和姓名及课程信息
hive>
select s.stu_id, s.stu_name, t1.score, t1.course_id, c.course_name from student_info s join ( select stu_id, score, course_id from score_info where score > 80 and course_id = '03' ) t1 on s.stu_id = t1.stu_id join course_info c on c.course_id = t1.course_id; 骚戴解法 select si2.stu_id , si2.stu_name, si.score, si.course_id , ci.course_name from score_info si join student_info si2 on si.stu_id = si2.stu_id join course_info ci on si.course_id = ci.course_id where ci.course_id ='03' and si.score >=80;
结果
s.stu_id s.stu_name t1.score t1.course_id c.course_name
002 胡歌 87 03 英语
004 刘德华 89 03 英语
005 唐国强 99 03 英语
013 蒋欣 93 03 英语
015 刘亦菲 84 03 英语
019 邓紫棋 93 03 英语
020 宋丹丹 81 03 英语
5.2 多表连接
5.2.1 课程编号为"01"且课程分数小于60,按分数降序排列的学生信息
hive>
select s.stu_id, s.stu_name, s.birthday, s.sex, t1.score from student_info s join ( select stu_id, course_id, score from score_info where score < 60 and course_id = '01' ) t1 on s.stu_id=t1.stu_id order by t1.score desc; 骚戴解法 select si2.stu_id , si2.stu_name, si2.birthday, si2.sex, si.score from score_info si join student_info si2 on si.stu_id = si2.stu_id join course_info ci on si.course_id = ci.course_id where ci.course_id ='01' and si.score <60 order by si.score desc;
结果
s.stu_id s.stu_name s.birthday s.sex t1.score 017 范冰冰 1992-07-04 女 58 008 吴京 1994-02-06 男 56 007 陈坤 1999-04-09 男 48 013 蒋欣 1997-11-08 女 47 019 邓紫棋 1994-08-31 女 46 012 杨紫 1996-12-21 女 44 018 李冰冰 1993-09-24 女 38
5.2.2 查询所有课程成绩在70分以上的学生的姓名、课程名称和分数,按分数升序排列
hive>
select s.stu_id, s.stu_name, c.course_name, s2.score from student_info s join ( select stu_id, sum(if(score >= 70,0,1)) flage from score_info group by stu_id having flage =0 ) t1 on s.stu_id = t1.stu_id left join score_info s2 on s.stu_id = s2.stu_id left join course_info c on s2.course_id = c.course_id;
骚戴理解:这里要有清晰的思路,首先通过子查询把所有课程都70分的学生id查出来,然后和student_info进行join,然后在和score_info进行left join,最后和course_info进行left join。注意顺序不能错!(因为子查询和student_info进行join的结果表只能先和score_info拼接),这里注意left join score_info s2 on s.stu_id = s2.stu_id语句的左边的驱动表是子查询和student_info进行join的结果表,然后我之前没有很好的理解多表联查的on后面的条件拼接,我以为在left join course_info c on s2.course_id = c.course_id;这里的on后面必须是student_info和course_info进行拼接,然而这两个表没发拼接!所以只要是join后的结果表和其他的表继续join,那么就可以使用join过的表的字段进行拼接,例如这里的left join course_info c on s2.course_id = c.course_id;语句的左边驱动表就是子查询和student_info进行join的结果表再和score_info进行left join的结果表,也就是能够和course_info进行join的on后面拼接的条件中可以使用之前的三个表的字段来连接,这里用的就是score_info和course_info拼接,拼接条件是 s2.course_id = c.course_id
结果
s.stu_id s.stu_name c.course_name s2.course
002 胡歌 语文 74
002 胡歌 数学 84
002 胡歌 英语 87
002 胡歌 体育 100
016 周冬雨 语文 71
016 周冬雨 数学 89
016 周冬雨 英语 71
016 周冬雨 体育 94
5.2.3 查询该学生不同课程的成绩相同的学生编号、课程编号、学生成绩
hive>
select sc1.stu_id, sc1.course_id, sc1.score from score_info sc1 join score_info sc2 on sc1.stu_id = sc2.stu_id where sc1.course_id <> sc2.course_id and sc1.score = sc2.score;
骚戴理解:这里用的是同一个表自己和自己join,理解一下这个自己join自己的场景
结果
sc1.stu_id sc1.course_id sc1.score
016 03 71
017 04 34
016 01 71
005 05 85
007 05 63
009 05 79
017 02 34
005 04 85
007 04 63
009 04 79
5.2.4 查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号
知识点:多表连接 + 条件
hive>
select s1.stu_id from ( select sc1.stu_id, sc1.course_id, sc1.score from score_info sc1 where sc1.course_id ='01' ) s1 join ( select sc2.stu_id, sc2.course_id, score from score_info sc2 where sc2.course_id ="02" )s2 on s1.stu_id=s2.stu_id where s1.score > s2.score;
结果
stu_id001005008010011013014015017019020
5.2.5 查询学过编号为“01”的课程并且也学过编号为“02”的课程的学生的学号、姓名
hive>
select t1.stu_id as `学号`, s.stu_name as `姓名` from ( select stu_id from score_info sc1 where sc1.course_id='01' and stu_id in ( select stu_id from score_info sc2 where sc2.course_id='02' ) )t1 join student_info s on t1.stu_id = s.stu_id;
骚戴理解:这里用的where...in....来处理学过编号为“01”的课程并且也学过编号为“02”的课程这个条件筛选
结果
学号 姓名
001 彭于晏
002 胡歌
004 刘德华
005 唐国强
006 陈道明
007 陈坤
008 吴京
009 郭德纲
010 于谦
011 潘长江
012 杨紫
013 蒋欣
014 赵丽颖
015 刘亦菲
016 周冬雨
017 范冰冰
018 李冰冰
019 邓紫棋
020 宋丹丹
5.2.6 查询学过“李体音”老师所教的所有课的同学的学号、姓名
hive>
select t1.stu_id, si.stu_name from ( select stu_id from score_info si where course_id in ( select course_id from course_info c join teacher_info t on c.tea_id = t.tea_id where tea_name='李体音' --李体音教的所有课程 ) group by stu_id having count(*)=2 --学习所有课程的学生 )t1 left join student_info si on t1.stu_id=si.stu_id; 骚戴解法 select si.stu_id , si.stu_name from ( select stu_id from score_info where course_id in ( select course_id from course_info where tea_id in( select tea_id from teacher_info where tea_name = '李体音' ) ) group by stu_id having count(*)=2 )t join student_info si on si.stu_id = t.stu_id;
结果
s.stu_id s.stu_name005 唐国强007 陈坤009 郭德纲
5.2.7查询学过“李体音”老师所讲授的任意一门课程的学生的学号、姓名
hive>
select t1.stu_id, si.stu_name from ( select stu_id from score_info si where course_id in ( select course_id from course_info c join teacher_info t on c.tea_id = t.tea_id where tea_name='李体音' ) )t1 left join student_info si on t1.stu_id=si.stu_id; 骚戴解法 SELECT si.stu_id , si.stu_name FROM ( SELECT stu_id FROM score_info WHERE course_id in ( SELECT course_id FROM course_info WHERE tea_id in( SELECT tea_id FROM teacher_info WHERE tea_name = '李体音' ) ) )t join student_info si on si.stu_id = t.stu_id;
结果
s.stu_id s.stu_name
001 彭于晏
002 胡歌
004 刘德华
005 唐国强
007 陈坤
009 郭德纲
010 于谦
013 蒋欣
014 赵丽颖
015 刘亦菲
016 周冬雨
017 范冰冰
018 李冰冰
020 宋丹丹
5.2.8 查询没学过"李体音"老师讲授的任一门课程的学生姓名
hive>
select stu_id, stu_name from student_info where stu_id not in ( select stu_id from score_info si where course_id in ( select course_id from course_info c join teacher_info t on c.tea_id = t.tea_id where tea_name='李体音' ) group by stu_id );
结果
stu_id stu_name003 周杰伦006 陈道明008 吴京011 潘长江012 杨紫019 邓紫棋
5.2.9查询至少有一门课与学号为“001”的学生所学课程相同的学生的学号和姓名
hive>
select si.stu_id, si.stu_name from score_info sc join student_info si on sc.stu_id = si.stu_id where sc.course_id in ( select course_id from score_info where stu_id='001' --001的课程 ) and sc.stu_id <> '001' --排除001学生 group by si.stu_id,si.stu_name; 骚戴理解 select stu_id , stu_name from student_info where stu_id not in ( select stu_id from score_info where course_id not in ( select course_id from score_info where stu_id = '001' ) );
结果
s1.stu_id s2.stu_name
002 胡歌
004 刘德华
005 唐国强
006 陈道明
007 陈坤
008 吴京
009 郭德纲
010 于谦
011 潘长江
012 杨紫
013 蒋欣
014 赵丽颖
015 刘亦菲
016 周冬雨
017 范冰冰
018 李冰冰
019 邓紫棋
020 宋丹丹
5.2.10 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
hive>
select si.stu_name, ci.course_name, sc.score, t1.avg_score from score_info sc join student_info si on sc.stu_id=si.stu_id join course_info ci on sc.course_id=ci.course_id join ( select stu_id, avg(score) avg_score from score_info group by stu_id )t1 on sc.stu_id=t1.stu_id order by t1.avg_score desc;
结果
t2.stu_name t2.course_name t2.score t1.avg_score
胡歌 体育 100 86.25
胡歌 数学 84 86.25
胡歌 英语 87 86.25
胡歌 语文 74 86.25
刘德华 体育 59 81.5
刘德华 语文 85 81.5
刘德华 英语 89 81.5
刘德华 数学 93 81.5
周冬雨 英语 71 81.25
周冬雨 数学 89 81.25
周冬雨 体育 94 81.25
周冬雨 语文 71 81.25
唐国强 数学 44 75.4
唐国强 音乐 85 75.4
唐国强 语文 64 75.4
唐国强 体育 85 75.4
唐国强 英语 99 75.4
郭德纲 音乐 79 74.2
郭德纲 体育 79 74.2
郭德纲 英语 60 74.2
郭德纲 语文 75 74.2
郭德纲 数学 78 74.2
陈道明 语文 71 73.33333333333333
陈道明 数学 90 73.33333333333333
陈道明 英语 59 73.33333333333333
……
李冰冰 音乐 87 58.0
李冰冰 语文 38 58.0
李冰冰 英语 49 58.0
李冰冰 数学 58 58.0
赵丽颖 数学 39 48.0
赵丽颖 语文 81 48.0
赵丽颖 体育 40 48.0
赵丽颖 英语 32 48.0
范冰冰 英语 55 45.25
范冰冰 体育 34 45.25
范冰冰 数学 34 45.25
范冰冰 语文 58 45.25
吴京 语文 56 43.0
吴京 数学 34 43.0
吴京 英语 39 43.0