Hive SQL初级练习(30题)

前言

Hive 的重要性不必多说,离线批处理的王者,Hive 用来做数据分析,SQL 基础必须十分牢固。

环境准备

建表语句

这里建4张表,下面的练习题都用这些数据。

-- 创建学生表
create table if not exists student_info(stu_id string COMMENT '学生id',stu_name string COMMENT '学生姓名',birthday string COMMENT '出生日期',sex string COMMENT '性别'
)
row format delimited fields terminated by ','
stored as textfile;-- 创建课程表
create table if not exists course_info(course_id string COMMENT '课程id',course_name string COMMENT '课程名',tea_id string COMMENT '任课老师id'
)
row format delimited fields terminated by ','
stored as textfile;-- 创建老师表
create table if not exists teacher_info(tea_id string COMMENT '老师id',tea_name string COMMENT '学生姓名'
)
row format delimited fields terminated by ','
stored as textfile;-- 创建分数表
create table if not exists score_info(stu_id string COMMENT '学生id',course_id string COMMENT '课程id',score int COMMENT '成绩'
)
row format delimited fields terminated by ','
stored as textfile;

数据

student_info.txt

001,彭于晏,1995-05-16,男
002,胡歌,1994-03-20,男
003,周杰伦,1995-04-30,男
004,刘德华,1998-08-28,男
005,唐国强,1993-09-10,男
006,陈道明,1992-11-12,男
007,陈坤,1999-04-09,男
008,吴京,1994-02-06,男
009,郭德纲,1992-12-05,男
010,于谦,1998-08-23,男
011,潘长江,1995-05-27,男
012,杨紫,1996-12-21,女
013,蒋欣,1997-11-08,女
014,赵丽颖,1990-01-09,女
015,刘亦菲,1993-01-14,女
016,周冬雨,1990-06-18,女
017,范冰冰,1992-07-04,女
018,李冰冰,1993-09-24,女
019,邓紫棋,1994-08-31,女
020,宋丹丹,1991-03-01,女

teacher_info.txt

1001,张高数
1002,李体音
1003,王子文
1004,刘丽英

course_info.txt

01,语文,1003
02,数学,1001
03,英语,1004
04,体育,1002
05,音乐,1002

score_info.txt

001,01,94
002,01,74
004,01,85
005,01,64
006,01,71
007,01,48
008,01,56
009,01,75
010,01,84
011,01,61
012,01,44
013,01,47
014,01,81
015,01,90
016,01,71
017,01,58
018,01,38
019,01,46
020,01,89
001,02,63
002,02,84
004,02,93
005,02,44
006,02,90
007,02,55
008,02,34
009,02,78
010,02,68
011,02,49
012,02,74
013,02,35
014,02,39
015,02,48
016,02,89
017,02,34
018,02,58
019,02,39
020,02,59
001,03,79
002,03,87
004,03,89
005,03,99
006,03,59
007,03,70
008,03,39
009,03,60
010,03,47
011,03,70
012,03,62
013,03,93
014,03,32
015,03,84
016,03,71
017,03,55
018,03,49
019,03,93
020,03,81
001,04,54
002,04,100
004,04,59
005,04,85
007,04,63
009,04,79
010,04,34
013,04,69
014,04,40
016,04,94
017,04,34
020,04,50
005,05,85
007,05,63
009,05,79
015,05,59
018,05,87

加载数据

加载数据到 Hive 的数据源目录

load data local inpath '/opt/module/hive-3.1.2/datas/student_info.txt' into table student_info;
load data local inpath '/opt/module/hive-3.1.2/datas/teacher_info.txt' into table teacher_info;
load data local inpath '/opt/module/hive-3.1.2/datas/course_info.txt' into table course_info;
load data local inpath '/opt/module/hive-3.1.2/datas/score_info.txt' into table score_info;

第一章 简单查询

1.1、查找特定条件

重点就是一个 where ,可能涉及到一点多表联结。

1.1.1 查询姓名中带“冰”的学生名单

简单的可以用 like 配合 % 和 _ ,复杂的可以使用 Hive 扩展的 rlike 配合正则表达式。 

-- 查询姓名中带“冰”的学生名单
select * from student_info where stu_name like '%冰%';

1.1.2 查询姓“王”老师的个数

-- 查询姓“王”老师的个数
select count(*) from teacher_info where tea_name like '王%';
-- 或者
select count(*) from teacher_info where tea_name rlike '^王';

1.1.3 检索课程编号为“04”且分数小于60的学生的课程信息,结果按分数降序排列

通过 course_id 联结两张表,找到不及格的成绩所对应的课程信息。

select c.* from course_info c
join score_info s on c.course_id = s.course_id
where c.course_id = 4 and s.score < 60
order by s.score desc;

1.1.4 查询数学成绩不及格的学生和其对应的成绩,按照学号升序排序

  1. 查询数学课对应的 course_id 
  2. 通过该 course_id 在 score_info 表中查出不及格的成绩的学生信息
  3. 通过学生信息中的 stu_id 字段将 score_info 表和 student_info 表联结起来,输出需要的字段(学生信息,成绩)。 
select stu.*,s.score from student_info stu
join (select * from score_infowhere course_id =(select course_id from course_info where course_name = '数学')
)son s.stu_id = stu.stu_id
where s.score < 60
order by stu.stu_id;

第二章 汇总分析

2.1 汇总分析

这里需要注意的是,聚合函数通常和 group by 配合使用!表示分组再做聚合处理。

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

--查询编号为“02”的课程的总成绩
select course_id,sum(score) from score_info where course_id = 02
group by course_id;

2.1.2 查询参加考试的学生个数

select count(distinct stu_id) from score_info;

2.2 分组

重点就是一个 group by。

2.2.1 查询各科成绩最高和最低的分,显示格式:课程号,最高分,最低分

不同的科目对应不同的 course_id ,所以我们用 group by course_id。

-- 同样这里有聚合函数配合 group by 来使用
select course_id,max(score) max,min(score) min from score_info
group by course_id;

2.2.2 查询每门课程有多少学生参加了考试

select course_id, count(stu_id) from score_info
group by course_id;

2.2.3 查询男生、女生人数

-- 查询男生、女生人数
select sex,count(stu_id) from student_info
group by sex;

2.3 分组结果的条件

重点就是 group by 之后的条件判断语句用 having。

2.3.1 查询平均成绩大于60分的学生的学号和平均成绩

这里需要先分组后判断,所以不能用 where,因为 group by 后面的条件语句只能是 having。

-- 这里需要分组后再判断条件
select stu_id,avg(score) avg_score from score_info
group by stu_id
having avg_score>60;

2.3.2 查询至少选修四门课程的学生学号

-- 查询至少选修四门课程的学生学号
select stu_id,count(course_id) cnt from score_info
group by stu_id
having cnt>=4;

2.3.3 查询同姓的学生名单并统计同姓人数大于2的姓

这里用到一个没用过的函数 substr() ,需要记忆一下。

select t1.first_name,count(stu_id) cnt from (select *,substr(stu_name,0,1) first_name from student_info)t1
group by t1.first_name
having cnt>=2;

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

多重排序判断直接逗号隔开即可。

-- 查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
select course_id,avg(score) avg_score from score_info
group by course_id
order by avg_score,course_id desc ;

2.3.5 统计参加考试人数大于等于15的学科

-- 统计参加考试人数大于等于15的学科
select course_id,count(*) cnt from score_info
group by course_id
having cnt>=15;

2.4 查询结果排序&分组指定条件

2.4.1 查询学生的总成绩并按照总成绩降序排序

-- 查询学生的总成绩并按照总成绩降序排序
select stu_id,sum(score) sum_score from score_info
group by stu_id
order by sum_score desc;

2.4.2 按照 学生id  语文    数学    英语   有效课程数      平均成绩 的格式输出成绩,没有成绩的记为 0

这里用到了 Hive 中的 if 语句,它的语法是:

IF(condition, true_value, false_value)

其中,condition是要评估的条件,true_value是当条件为真时要返回的值,false_value是当条件为假时要返回的值。

比如;

SELECT name, age, IF(age >= 18, 'Adult', 'Minor') AS age_group  
FROM users;

此外,还可以使用多重 if 嵌套语句:

SELECT name, age,   IF(age >= 18 AND gender = 'Male', 'Adult Male',   IF(age >= 18 AND gender = 'Female', 'Adult Female',   IF(age < 18 AND gender = 'Male', 'Minor Male', 'Minor Female'))) AS age_group  
FROM users;

本题:这里的反引号是引用的作用,这里代表的是 列名。

select s.stu_id,sum(if(c.course_name='语文',score,0)) `语文`,sum(if(c.course_name='数学',score,0)) `数学`,sum(if(c.course_name='英语',score,0)) `英语`,count(*) `有效课程数`,avg(s.score) `平均成绩`
from score_info sjoin course_info c on s.course_id = c.course_id
group by s.stu_id
order by `平均成绩` desc ;

2.4.3 查询一共参加三门课程且其中一门为语文课程的学生的id和姓名

有点复杂,需要好好理解掌握。

-- 查询一共参加三门课程且其中一门为语文课程的学生的id和姓名
select t2.stu_id,s.stu_name from (
select t1.stu_id from (select stu_id,course_id from score_info where stu_id in (select stu_id from score_infowhere course_id = '01') -- 筛选出有语文成绩的学生的id) t1 group by t1.stu_idhaving count(t1.course_id)=3) t2
join student_info s on t2.stu_id = s.stu_id;

第三章 复杂查询

3.1 子查询

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

我们根据 stu_id 把每个学生的成绩信息聚合在一起。然后巧妙的使用了 if 语句来判断是否有不及格的科目,如果>=60分,结果+1,最后用 sum 函数统计出结果,如果 sum 等于0,则说明全部不及格。

-- 查询所有课程成绩均小于60分的学生的学号、姓名
select t1.stu_id,s.stu_name from(select stu_id,sum(if(score>=60,1,0)) flag from score_infogroup by stu_idhaving flag=0) t1
join student_info s on s.stu_id = t1.stu_id;

3.1.2 查询没有学全所有课的学生的学号、姓名

这里需要注意:

  1. 在Hive SQL中,子查询的结果可能返回多行数据,因此需要使用IN关键字而不是=关键字。IN关键字用于匹配子查询结果中的任何一个值,而=关键字只能匹配单个值。
  2. group by 不一定必须和聚合函数搭配使用,比如下面的查询 course_info 表的行数。
-- 查询没有学全所有课的学生的学号、姓名
select stu_id, stu_name
from student_info
where stu_id not in (select stu_idfrom score_infogroup by stu_idhaving count(distinct course_id) = (select count(distinct course_id) from course_info)
);

 

3.1.3 查询出只选修了三门课程的全部学生的学号和姓名

这里同样需要注意:当子查询的结果是多行值时,用 in 而不是 = !

-- 查询出只选修了三门课程的全部学生的学号和姓名
select stu_id,stu_name from student_info where stu_id in (select stu_id from score_infogroup by stu_idhaving count(course_id)=3);


第四章 多表查询

4.1 表联结

4.1.1 查询有两门以上的课程不及格的同学的姓名及其平均成绩

-- 查询有两门以上的课程不及格的同学的姓名及其平均成绩
select stu_name,avg_score from student_info st join (select stu_id,avg(score) avg_score from score_infogroup by stu_idhaving sum(if(score<60,1,0))>=2) t1
on st.stu_id=t1.stu_id;

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

-- 查询所有学生的学号、姓名、选课数、总成绩
select t1.stu_id,s.stu_name,cnt,sum_score from (select stu_id,count(course_id) cnt,sum(score) sum_score from score_infogroup by stu_id)t1 join student_info s
on t1.stu_id=s.stu_id;

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

-- 查询平均成绩大于85的所有学生的学号、姓名和平均成绩
select t1.stu_id,s.stu_name,avg from (select stu_id,avg(score) avg from score_infogroup by stu_idhaving avg>85)t1 join student_info s
on t1.stu_id=s.stu_id;

4.1.4 查询学生的选课情况:学号,姓名,课程号,课程名称

-- 查询学生的选课情况:学号,姓名,课程号,课程名称
select t1.stu_id,s.stu_name,t1.course_id,c.course_name from(select stu_id,course_id from score_info)t1
join student_info s
on t1.stu_id=s.stu_id
join course_info c
on c.course_id=t1.course_id;

输出结果明显按照科目分开, 前几行都是选语文的学生信息。

或者

-- 查询学生的选课情况:学号,姓名,课程号,课程名称
select t1.stu_id,s.stu_name,t1.course_id,c.course_name from(select stu_id,course_id from score_infogroup by stu_id, course_id)t1
join student_info s
on t1.stu_id=s.stu_id
join course_info c
on c.course_id=t1.course_id;

这里的输出结果明显按照姓名分开,前几行都是同一个学生的选课信息(这里的 group by要么指定两个字段(即我们要查询的 stu_id 和 course_id),要么就不需要 group by)。 

4.1.5 查询出每门课程的及格人数和不及格人数

-- 查询出每门课程的及格人数和不及格人数
select c.course_name,`及格人数`,`不及格人数` from (select course_id,sum(if(score>=60,1,0)) `及格人数`,sum(if(score<60,1,0)) `不及格人数` from score_infogroup by course_id)t1
join course_info c
on t1.course_id=c.course_id;

4.1.6 查询课程编号为03且课程成绩在80分以上的学生的学号和姓名及课程信息

这里需要注意如果查询结果中没有用到聚合函数就少用 group by,因为group by会触发生成 mapreduce 程序;能用 where 最好,因为 where 不会触发产生 mapreduce 程序;where 可以秒出结果,而 group by需要好多秒。

-- 查询课程编号为03且课程成绩在80分以上的学生的学号和姓名及课程信息
select t1.stu_id,s.stu_name,c.course_name from (select stu_id,course_id from score_infowhere course_id=03 and score>80)t1
join course_info c
on t1.course_id=c.course_id
join student_info s
on t1.stu_id=s.stu_id;

4.2 多表连接

4.2.1 课程编号为"01"且课程分数小于60,按分数降序排列的学生信息

-- 课程编号为"01"且课程分数小于60,按分数降序排列的学生信息
select s.*,t1.score from student_info s join (select stu_id,score from score_infowhere course_id=01 and score<60)t1
on s.stu_id=t1.stu_id
order by t1.score desc;

4.2.2 查询所有课程成绩在70分以上的学生的姓名、课程名称和分数,按分数升序排列

-- 查询所有课程成绩在70分以上的学生的姓名、课程名称和分数,按分数升序排列
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)) flag from score_infogroup by stu_idhaving flag=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;

4.2.3 查询该学生不同课程的成绩相同的学生编号、课程编号、学生成绩

4.2.4 查询课程编号为“01”的课程比“02”的课程成绩高的所有学生的学号

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

4.2.6 查询学过“李体音”老师所教的所有课的同学的学号、姓名

4.2.7 查询学过“李体音”老师所讲授的任意一门课程的学生的学号、姓名

4.2.8 查询没学过"李体音"老师讲授的任一门课程的学生姓名

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

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

总结

练习完这些练习题之后,明显发现自己有了很大的提升,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/91968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yolov5分割+检测c++ qt 中部署,以opencv方式(详细代码(全)+复制可用)

1&#xff1a;版本说明&#xff1a; qt 5.12.10 opencv 4.5.3 &#xff08;yolov5模型部署要求opencv>4.5.0&#xff09; 2&#xff1a;检测的代码 yolo.h #pragma once #include<iostream> #include<cmath> #include<vector> #include <opencv2/…

毅速课堂:3D打印随形水路在小零件注塑中优势明显

小零件注塑中的冷却不均匀问题常常导致烧焦现象的发生。这主要是因为传统机加工方法无法制造出足够细小的水路&#xff0c;以适应小零件的复杂形状。而3D打印技术的引入&#xff0c;尤其是随形水路的设计&#xff0c;为解决这一问题提供了新的解决方案。 3D打印随形水路技术的优…

TS编译选项——编译TS文件同时对JS文件进行编译

一、允许对JS文件进行编译 我们在默认情况下编译TS项目时是不能编译js文件的&#xff0c;如下图中的hello.js文件并未编译到dist目录下&#xff08;这里配置了编译文件放到dist目录下&#xff09; 如果我们想要实现编译TS文件同时对JS文件进行编译&#xff0c;就需要在tsconfi…

使用U3D、pico开发VR(二)——添加手柄摇杆控制移动

一、将unity 与visual studio 相关联 1.Edit->Preference->External tool 选择相应的版本 二、手柄遥控人物转向和人物移动 1.添加Locomotion System组件 选择XR Origin&#xff1b; 2.添加Continuous Move Provider&#xff08;Action-based&#xff09;组件 1>…

编程每日一练(多语言实现)基础篇:求总数问题

文章目录 一、实例描述二、技术要点三、代码实现3.1 C 语言实现3.2 Python 语言实现3.3 Java 语言实现3.4 JavaScript 语言实现 一、实例描述 集邮爱好者把所有的邮票存放在三个集邮册中&#xff0c;在A册内存放全部的十分之二&#xff0c;在B册内存放不知道是全部的七分之几&…

MyBatis的一级缓存和二级缓存:原理和作用

MyBatis的一级缓存和二级缓存&#xff1a;原理和作用 引言 在数据库访问中&#xff0c;缓存是一种重要的性能优化手段&#xff0c;它可以减少数据库查询的次数&#xff0c;加快数据访问速度。MyBatis作为一款流行的Java持久层框架&#xff0c;提供了一级缓存和二级缓存来帮助…

基于Java的大学生就业招聘系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【数据结构】排序算法(一)—>插入排序、希尔排序、选择排序、堆排序

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.直接插入排序 2.希尔排序 3.直接选择排…

OpenCV之分水岭算法(watershed)

Opencv 中 watershed函数原型&#xff1a; void watershed( InputArray image, InputOutputArray markers ); 第一个参数 image&#xff0c;必须是一个8bit 3通道彩色图像矩阵序列&#xff0c;第一个参数没什么要说的。关键是第二个参数 markers&#xff0c;Opencv官方文档的说…

全网最全Python系列教程(非常详细)---集合讲解(学Python入门必收藏)

&#x1f9e1;&#x1f9e1;&#x1f9e1;这篇是关于Python中集合的讲解&#xff0c;涉及到以下内容&#xff0c;欢迎点赞和收藏&#xff0c;你点赞和收藏是我更新的动力&#x1f9e1;&#x1f9e1;&#x1f9e1; 1、集合是什么&#xff1f; 2、集合应该怎么去定义&#xff1f…

搭建前端框架

在终端进入web目录&#xff0c;然后创建vuecrud工程 创建工程并引入ElementUI和axios手把手教学>传送门:VueCLI脚手架搭建

力扣 -- 718. 最长重复子数组

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int findLength(vector<int>& nums1, vector<int>& nums2) {int m nums1.size();int n nums2.size();//多开一行&#xff0c;多开一列vector<vector<int>> dp(m 1, ve…

Ghostscript 在 Linux 和 Windows 系统的应用与问题解决

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

背诵不等于理解,深度解析大模型背后的知识储存与提取

自然语言模型的背诵 (memorization) 并不等于理解。即使模型能完整记住所有数据&#xff0c;也可能无法通过微调 (finetune) 提取这些知识&#xff0c;无法回答简单的问题。 随着模型规模的增大&#xff0c;人们开始探索大模型是如何掌握大量知识的。一种观点认为这归功于 “无…

【ARMv8 SIMD和浮点指令编程】NEON 加载指令——如何将数据从内存搬到寄存器(其它指令)?

除了基础的 LDx 指令,还有 LDP、LDR 这些指令,我们也需要关注。 1 LDNP (SIMD&FP) 加载 SIMD&FP 寄存器对,带有非临时提示。该指令从内存加载一对 SIMD&FP 寄存器,向内存系统发出访问是非临时的提示。用于加载的地址是根据基址寄存器值和可选的立即偏移量计算…

计算机网络(一):概述

参考引用 计算机网络微课堂-湖科大教书匠计算机网络&#xff08;第7版&#xff09;-谢希仁 1. 计算机网络在信息时代的作用 计算机网络已由一种通信基础设施发展成为一种重要的信息服务基础设施计算机网络已经像水、电、煤气这些基础设施一样&#xff0c;成为我们生活中不可或…

网络协议--概述

1.2 分层 网络协议通常分不同层次进行开发&#xff0c;每一层分别负责不同的通信功能。一个协议族&#xff0c;比如TCP/IP&#xff0c;是一组不同层次上的多个协议的组合。 TCP/IP通常被认为是一个四层协议系统&#xff0c;如图1-1所示。每一层负责不同的功能&#xff1a; 1.链…

【Vue.js】使用Element中的Mock.js搭建首页导航左侧菜单---【超高级教学】

一&#xff0c;Mock.js 1.1 认识Mock.js Mock.js是一个用于前端开发中生成随机数据、模拟接口响应的 JavaScript 库。模拟数据的生成器&#xff0c;用来帮助前端调试开发、进行前后端的原型分离以及用来提高自动化测试效率 总结来说&#xff0c;Element中的Mock.js是一个用于…

ClassNotFoundException与NoClassDefFoundError

如果这springboot服务启动时两个报错同时出现&#xff0c;那大概率是依赖间冲突导致的 查资料发现是springcloud的依赖版本和springboot的依赖版本不兼容&#xff0c;顺藤摸瓜找到springcloud jar包中调用org.springframework.boot.context.properties.ConfigurationProperties…

《MySQL高级篇》十六、主从复制

文章目录 1、主从复制概述1.1 如何提升数据库并发能力1.2 主从复制的作用 2、主从复制的原理2.1 原理剖析2.2 复制的基本原则 3、一主一从架构搭建3.1 准备工作3.2 主机配置文件3.3 从机配置文件3.4 主机&#xff1a;建立账户并授权3.5 从机&#xff1a;配置需要复制的主机3.6 …