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閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容