Hive 的几个练习题

题目1

需求:
每个用户截止到每月为止的最大单月访问次数和累计到该月的总访问次数

三个字段的意思:
用户名,月份,访问次数

数据:
A,2015-01,5
A,2015-01,15
B,2015-01,5
A,2015-01,8
B,2015-01,25
A,2015-01,5
A,2015-02,4
A,2015-02,6
B,2015-02,10
B,2015-02,5
A,2015-03,16
A,2015-03,22
B,2015-03,23
B,2015-03,10
B,2015-03,11

最后结果展示:

用户 月份 最大访问次数 总访问次数 当月访问次数
A 2015-01 33 33 33
A 2015-02 33 43 10
A 2015-03 38 81 38
B 2015-01 30 30 30
B 2015-02 30 45 15
B 2015-03 44 89 44

解题思路

  1. 以username分和month分组,统计出每月访问次数,得到如下结果
    CREATE TABLE t01_s1 AS
    SELECT table01.username, table01. MONTH, sum(table01.count) sum FROM myhive.table01 GROUP BY table01.username, table01. MONTH;

  2. 进行自连接,选出tl.month>tr.month的字段,并用username和month分组就可以得到结果
    SELECT tl.username, tl. MONTH, max(tr.sum) maxvisit, sum(tr.sum) sumvisit, max(tl.sum) currentmonth
    FROM t01_s1 tl JOIN t01_s1 tr ON tl.username = tr.username
    WHERE tl. MONTH >= tr. MONTH
    GROUP BY tl.username, tl. MONTH;

进行自连接后的结果如下:

tl.username     tl.month        tl.sum  tr.username     tr.month        tr.sum
A       2015-01 33      A       2015-01 33
A       2015-02 10      A       2015-01 33
A       2015-03 38      A       2015-01 33
A       2015-01 33      A       2015-02 10
A       2015-02 10      A       2015-02 10
A       2015-03 38      A       2015-02 10
A       2015-01 33      A       2015-03 38
A       2015-02 10      A       2015-03 38
A       2015-03 38      A       2015-03 38
B       2015-01 30      B       2015-01 30
B       2015-02 15      B       2015-01 30
B       2015-03 44      B       2015-01 30
B       2015-01 30      B       2015-02 15
B       2015-02 15      B       2015-02 15
B       2015-03 44      B       2015-02 15
B       2015-01 30      B       2015-03 44
B       2015-02 15      B       2015-03 44
B       2015-03 44      B       2015-03 44

题目2

// 建表语句:
CREATE TABLE course (
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
sid int(11) DEFAULT NULL,
course varchar(255) DEFAULT NULL,
score int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

// 插入数据
// 字段解释:id, 学号, 课程, 成绩
INSERT INTO course VALUES (1, 1, 'yuwen', 43);
INSERT INTO course VALUES (2, 1, 'shuxue', 55);
INSERT INTO course VALUES (3, 2, 'yuwen', 77);
INSERT INTO course VALUES (4, 2, 'shuxue', 88);
INSERT INTO course VALUES (5, 3, 'yuwen', 98);
INSERT INTO course VALUES (6, 3, 'shuxue', 65);

求:所有数学课程成绩 大于 语文课程成绩的学生的学号

解答:

  1. 自连接的方式:
    select c1.* from course c1 join course c2 on c1.sid=c2.sid where c1.score>c2.score and c1.course='shuxue';

  2. 行列转换的方式
    select a.sid from (select sid,
    max(case when course='yuwen'then score else 0 end) yuwen,
    max(case when course='shuxue'then score else 0 end) shuxue
    from course group by sid having shuxue>yuwen) a;

题目3

数据:
2014010114
2014010216
2014010317
2014010410
2014010506
2012010609
2012010732
2012010812
2012010919
2012011023
2001010116
2001010212
2001010310
2001010411
2001010529
2013010619
2013010722
2013010812
2013010929
2013011023
2008010105
2008010216
2008010337
2008010414
2008010516
2007010619
2007010712
2007010812
2007010999
2007011023
2010010114
2010010216
2010010317
2010010410
2010010506
2015010649
2015010722
2015010812
2015010999
2015011023

要求: 求出一年中出现最高温度的那一天
输出以下数据:
20010105 29
20070109 99
20080103 37
20100103 17
20120107 32
20130109 29
20140103 17
20150109 99

解题

解法一:
SELECT * FROM exercise3
WHERE concat( substr(DATA, 1, 4), substr(DATA, 9, 2))
IN ( SELECT concat( substr(DATA, 1, 4), max(substr(DATA, 9, 2))) FROM exercise3 GROUP BY substr(DATA, 1, 4));
思路:通过年份分组求出最高温度的那一年和最高温度,把这些数据看成一个集合。再查出原始表中出现这些数据的那一行。

解法二:
select substring(b.line, 1, 8) as max_temp_date, a.max_temp
from exercise3 b join
(select substring(c.line, 1, 4) as year, max(substring(c.line, -2)) as max_temp
from exercise3 c group by substring(c.line, 1, 4)) a
on a.year = substring(b.line, 1, 4) and
a.max_temp = substring(b.line, -2);
思路:1. 求出以你那为分组,求出最最高温度和年份

  1. 用原始表和这个表进行连接,连接条件为年份相同且最高温度相同的条目

题目4

现有一份以下格式的数据:
表示有id为1,2,3的学生选修了课程a,b,c,d,e,f中其中几门:
数据:
id course
1,a
1,b
1,c
1,e
2,a
2,c
2,d
2,f
3,a
3,b
3,c
3,e

编写Hive的HQL语句来实现以下结果:
表中的1表示选修,表中的0表示未选修
id a b c d e f
1 1 1 1 0 1 0
2 1 0 1 1 0 1
3 1 1 1 0 1 0

解题要点行列转换。
解法1:
select id,
sum(case course when "a" then 1 else 0 end) as a,
sum(case course when "b" then 1 else 0 end) as b,
sum(case course when "c" then 1 else 0 end) as c,
sum(case course when "d" then 1 else 0 end) as d,
sum(case course when "e" then 1 else 0 end) as e,
sum(case course when "f" then 1 else 0 end) as f
from id_course group by id;

解法2:
先构造以下表
id id_courses courses
1 ["a","b","c","e"] ["a","b","c","d","e","f"]
2 ["a","c","d","f"] ["a","b","c","d","e","f"]
3 ["a","b","c","e"] ["a","b","c","d","e","f"]

1.左边:
select d.id as id, collect_set(d.course) as id_courses from id_course d group by d.id;

  1. 右边:
    select sort_array(collect_set(course)) as tt from id_course;

  2. 左右连接得到需要的表:
    create id_courses table as
    select a.id, a.id_courses, b.tt
    from
    (select d.id as id, collect_set(d.course) as id_courses from id_course d group by d.id) a
    join
    (select sort_array(collect_set(c.course)) as tt from id_course c) b ;

  3. 查询出最终结果
    使用if判断
    select
    id,
    if(array_contains(a.id_courses, courses[0]),1,0) as a,
    if(array_contains(a.id_courses, courses[1]),1,0) as b,
    if(array_contains(a.id_courses, courses[2]),1,0) as c,
    if(array_contains(a.id_courses, courses[3]),1,0) as d,
    if(array_contains(a.id_courses, courses[4]),1,0) as e,
    if(array_contains(a.id_courses, courses[5]),1,0) as f
    from id_courses a;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容