1. 程式人生 > 其它 >MYSQL/HIVESQL筆試題:HIVESQL(一)分組求TopN/行轉列/列轉行

MYSQL/HIVESQL筆試題:HIVESQL(一)分組求TopN/行轉列/列轉行

1 分組求TopN

一、先看資料:

使用HiveSQL常用的方式為:

Select * from table,
row_number() over(partition by item order by score desc) rank
where rank<=2;

二、輸出結果為:

三、解析:row_number()函式基於over物件分組、排序的記過,為每一行分組記錄返回一個序號,該序號從1開始,依次遞增,遇到新組則重新從1開始。也就是說,該函式計算的值表示每組內部排序後的順序編號。

然後在語句中加入限制條件rank<=2來篩選具體選取top幾。從最終的結果可以看出,語文成績考試前兩名的同學分別是建國和小編、數學成績排名前兩名的同學分別是建國和狗剩。

2 行轉列/列轉行

一、資料如下:

現在需要轉換為:

二、使用hive實現需求的話,可以使用:

Select
name,
sum(case when item=數學 then score end) as math,
sum(case when item=英語 then score end) as english,
From table
Group by name

三、解析:首先寫出select name from table group by name, 因為select後有幾個欄位,最終輸出就是幾個欄位,所以我們需要把目標資料的”math”和“english”兩個欄位想辦法得出來。

之後可以對item欄位所有列舉的結果進行case when判斷,將score填值進入,因為最後我們需要對name做一下聚合,需要明確的是一般選取欄位一定要出現在groupby裡面。

聚合函式可以不用,所以我們在外面套一層sum做聚合,這樣得到sum的結果和單人得分結果是一致的,因為我們以name做了一遍聚合,而每個使用者對一門課程只有一個成績,所以這樣就可以得到最終結果。

3 將“表-4”的內容轉換為“表-3”的內容

select table_4.name,
a.item,
a.score
from table_4
lateral view explode(
str_to_map(concat('math=',math,'&english=',english),'&','=')
) a as item,score;

解析:首先使用str_to_map函式將math欄位與english欄位拼接後的結果轉換為map型別,然後通過側檢視和explode函式將其爆炸開,給生成的臨時側檢視一個名字,取名a並給列名取名為item,score,因為explode(map)爆炸的結果是每一個item為行,key為1列,value為1列,這樣就恰好形成我們想要的結果。這個示例理解起來稍微有點難度,大家不熟悉這些函式的用法的話,可以首先熟悉一下。