2014-10-09 84 views
3

我在Hive中使用5列(即email,a_first_date,b_first_date,c_first_date,d_first_date)創建表。Hive(查找連續n列的最小值)

a,b,c,d是用戶可以採取的4種不同的動作,並且上表中的4列表示用戶進行第一個相應動作的日期。例如,'a_first_date'中的值具有用戶執行操作的日期。

輸出:我想要的是2列有電子郵件,overall_first_date,即用戶做了他的第一個動作的日期?

示例表:(假設所有的值均大於其他電子郵件BIGINT型)

電子郵件,a_first_date,b_first_date,c_first_date,d_first_date
ABC,20140707,20140702,20140801,20140907
XYZ,20140107,20140822, 20140201,20141007

輸出:

電子郵件,overall_first_date
ABC,20140702
XYZ,20140107

可能的解決方案是編寫UDF或使用IF ELSE將這些值相互比較,然後找到最小值,但這會涉及大量比較。

或者我可以做:

select email, min(action) as overall_first_date from 

(
select email, a_first_date as action from mytable 
UNION ALL 
select email, b_first_date as action from mytable 
UNION ALL 
select email, c_first_date as action from mytable 
UNION ALL 
select email, d_first_date as action from mytable 
) q1 

GROUP BY email 

但同樣,這不是一個好辦法。

任何人都可以請建議一個更好的方式來實現這一目標嗎?

+0

看到這個問題: http://stackoverflow.com/questions/7598150/get-the-minimum-value-between-several-columns – programmer43229 2014-10-09 11:27:19

回答

4

你可以使用蜂巢的陣列功能:

select email, 
     sort_array(array(a_first_date, b_first_date, c_first_date, d_first_date))[0] as overall_first_date 
from table; 

我不知道如何與此相比,一個CASE語句的性能,明智的。既然你沒有很多列,兩者同樣簡單。

+0

這肯定比CASE更整潔。真棒! – Espanta 2017-01-27 16:16:40

2

使用函數least()。例如, ; 從Tablename中選擇*,至少(col1,col2,col3)作爲minofcol ;