我在Hive中有一个包含5列的表,即email,a_first_date,b_first_date,c_first_date,d_first_date。
a,b,c,d是用户可以采取的4种不同的动作,上表中的4列表示用户进行第一次相应动作的日期。例如,'a_first_date'中的值包含用户执行操作a的日期。
输出:我想要的是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 :(得分:5)
您可以使用Hive的数组函数:
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语句在性能方面的比较。由于你没有很多专栏,所以两者都同样简单。
答案 1 :(得分:5)
使用函数least()。 例如; 选择*,至少(col1,col2,col3)作为minofcol 来自Tablename;
答案 2 :(得分:2)