2015-09-23 30 views
1

我有一個表,它具有ip,session_id,小時。 我想彙總這些數據,並最終得到一個新的表格,每個表格都有一個每小時會話數量小時聚合的記錄。HIVE構建ARRAY使用列作爲索引和聚合值作爲值

要做到這一點,我開始與子查詢,

SELECT ip, count(session_id) as sessions, hour 
FROM current_table 
GROUP BY ip,hour; 

這會給我(最多)24條記錄與相應記錄特定小時會話數每個IP。使用此子查詢我想填補一個數組(說hourly_sessions是我一起工作的陣列)類似,

hourly_sessions[hour] = sessions 

所以,我最終會與每個IP和數組索引關聯數組代表其小時我想要檢查會話聚合。如果在特定小時內沒有會話,我希望它顯示0.

如何在HIVE中使用/不使用UDF來實現此目的? 我現在的(哈克和不完全)的方法是使用類似:

collect_set(concat_ws(",",hour,cast(sessions) as STRING)) 

但是這需要每個需要特定的每小時總時間解析整個陣列。

+0

你需要填寫的數據差距,所以如果一個IP沒有會話一個小時,該數組包含爲0的會話數的入口? – mattinbits

+0

是的,那是我理想中想要的。 –

回答

0

首先我想你需要看看如何填補你的數據中的任何空白。在(ip,小時)對方面。這樣做的一個方法是創建的小時表:

CREATE TABLE HOURS AS Select explode(Array(0,1,2...,23)) as hour; 

然後不同的IPS的表:

CREATE TABLE IPS AS SELECT distinct ip from current_table; 

然後加入他們的行列:

CREATE TABLE IP_HOURS AS SELECT IPS join HOURS; 

這給了你23項爲每個IP。用您的實際計數加入此:

CREATE TABLE ACTUAL_COUNTS AS 
    SELECT ip, count(session_id) as sessions, hour 
    FROM current_table 
    GROUP BY ip,hour; 

CREATE TABLE NO_GAP_COUNTS AS 
    SELECT a.ip as ip, a.hour as hour, COALESCE(b.sessions, 0) as sessions 
    FROM IP_HOURS a LEFT JOIN ACTUAL_COUNTS b ON (a.ip = b.ip AND a.hour = b.hour) 

您可以使用此表原樣,但如果你真的想每小時數壓縮到一個數組所以你必須每個ID一行,您可以使用Brickhouse「收集「UDF,因爲它會保持會話計數的順序,如果你先通過ip命令數據,小時。內置的Hive collect_set不保證保持順序。

Is Hive's collect_list ordered?

+0

謝謝,這非常有幫助!這照顧了0條目問題。我會看看Brickhouse收集來構建陣列。 –

相關問題