1. 程式人生 > >hive面試之【自連線,行轉列,列轉行】

hive面試之【自連線,行轉列,列轉行】

現有這麼一批資料,現要求出:
每個使用者截止到每月為止的最大單月訪問次數和累計到該月的總訪問次數

三個欄位的意思:
使用者名稱,月份,訪問次數

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、按照使用者分組
2、按照月份排序
3、求max和sum(在以上兩點的基礎之上)



準備資料和表:

create database exercise;
use exercise;
drop table if exists visit;
create table visit(username string, month string, visit int) row format delimited fields terminated by ",";
load data local inpath "/home/hadoop/visit.txt" into table visit;
select * from visit;



思路:

1、從資料當中發現數據規律:
	每個使用者在每月的訪問記錄有多條
	解決方法:先求每個使用者在每個月份裡面的總訪問次數

// 第一個HQL語句:
create table visit_month as select username, month , sum(visit) visit from visit group by username, month order by username, month;

使用者	月份			當月訪問次數
A	2015-01			  33
A	2015-02			  10
A	2015-03			  38
B	2015-01			  30
B	2015-02	                  15
B	2015-03		          44


2、求出截止到每月時的單月最大訪問次數 和總訪問次數

A 2015-01 33   ====>   A 2015-01 33 33 33


A 2015-01 33
A 2015-02 10   =====>  A 2015-02 10 33 43

......



最終的資料結果:

A	2015-01	 (33)
A	2015-02	 (33,10)
A	2015-03	 (33,10, 43)
B	2015-01	 (33)
B	2015-02	 (33,10)
B	2015-03	 (33,10, 43)


轉換資料形式:
A	2015-01	 33	2015-01

A	2015-02	 33	2015-01
A	2015-02	 10	2015-02

a.username  a.month  b.visit   b.month
A	2015-03	| 33	2015-01
A	2015-03	| 10	2015-02
A	2015-03	| 43	2015-03


a.username  a.month  a.visit    b.visit   b.month   b.username
A	2015-01     33		33	2015-01		A
A	2015-01     33		10	2015-02		A   XXX
A	2015-01     33		43	2015-03		A   xxx

A	2015-02     10		33	2015-01		A
A	2015-02     10		10	2015-02		A
A	2015-02     10		43	2015-03		A   xxx

A	2015-03     43		33	2015-01		A
A	2015-03     43		10	2015-02		A
A	2015-03     43		43	2015-03		A

正常資料;
A	2015-01	 33
A	2015-02	 10
A	2015-03	 43

select username, month, sum(visit) totalVisit, max(visit) maxVisit from visit_month;

使用自連線的方式就能造出能夠分組,能夠求聚合的欄位列:


// 第二個 HQL 語句,, 建立一個view
create view visit_join as select a.username aname, a.month amonth,  a.visit avisit, 
b.username bname, b.month bmonth,  b.visit bvisit from visit_month a 
join visit_month b on a.username = b.username;


結果:該view當中 總共有  18 條記錄  3*3 + 3*3

// 第三個 qhl語句,, 最終的sql語句:
create table lastvisit as select aname, amonth, avisit, sum(bvisit) as totalvisit, max(bvisit) as maxvisit from visit_join where amonth >= bmonth group by aname, amonth, avisit;

A       2015-01 33      33      33
A       2015-02 10      43      33
A       2015-03 38      81      38
B       2015-01 30      30      30
B       2015-02 15      45      30
B       2015-03 44      89      44

sum(yuwen)  max()  聚合操作 : 把多行當中的相同的列的值做聚合操作

sum(yingyu, shuxue, yuwen) = 把一行當中的多列的值 做累加