我有一个日期分区的Hive表,每个用户都有一行。它有一个activity_log列,其值为1或0,具体取决于用户是否在该日期执行了该活动。
我也有一个UDF,就像dayOfWeek(),它给了我一周中某一天的日期。
我正在尝试创建一个包含过去一周用户活动的表。因此,列将是:
user, activity_log_mon, activity_log_tue, activity_log_wed, ...activity_log_sun
每个activity_log列的值应为1或0,表示用户是否在过去一周的那一天执行了该活动。
这是一个给我几乎所需的查询:
SELECT user,
IF(dayOfWeek(date)='sun', activity_log , NULL) as activity_log_sun,
IF(dayOfWeek(date)='mon', activity_log , NULL) as activity_log_mon,
IF(dayOfWeek(date)='tue', activity_log , NULL) as activity_log_tue,
IF(dayOfWeek(date)='wed', activity_log , NULL) as activity_log_wed,
IF(dayOfWeek(date)='thu', activity_log , NULL) as activity_log_thu,
IF(dayOfWeek(date)='fri', activity_log , NULL) as activity_log_fri,
IF(dayOfWeek(date)='sat', activity_log , NULL) as activity_log_sat
FROM user_activity_table
WHERE date >= '2015-08-18' AND date <= '2015-08-24'
但这会为每个用户提供7行,如下所示:
user activity_log_sun activity_log_mon .... activity_log_sat
abcd 1 NULL NULL
abcd NULL 0 NULL
...
abcd NULL NULL 1
我真正想要的是一个每个用户只有一行的表,如下所示:
user activity_log_sun activity_log_mon .... activity_log_sat
abcd 1 0 1
如何重新组合这样的行?或者,首先获得这样的行的最佳方法是什么?
答案 0 :(得分:1)
这是我最终做的事情:
SELECT user,
SUM(activity_log_sun),
SUM(activity_log_mon),
SUM(activity_log_tue),
SUM(activity_log_wed),
SUM(activity_log_thu),
SUM(activity_log_fri),
SUM(activity_log_sat)
FROM (
SELECT user,
IF(dayOfWeek(date)='sun', activity_log , NULL) as activity_log_sun,
IF(dayOfWeek(date)='mon', activity_log , NULL) as activity_log_mon,
IF(dayOfWeek(date)='tue', activity_log , NULL) as activity_log_tue,
IF(dayOfWeek(date)='wed', activity_log , NULL) as activity_log_wed,
IF(dayOfWeek(date)='thu', activity_log , NULL) as activity_log_thu,
IF(dayOfWeek(date)='fri', activity_log , NULL) as activity_log_fri,
IF(dayOfWeek(date)='sat', activity_log , NULL) as activity_log_sat
FROM user_activity_table
WHERE date >= '2015-08-18' AND date <= '2015-08-24'
) t
GROUP BY user
答案 1 :(得分:0)
观察以下HiveQL的行为:
SELECT COALESCE(collected[0], collected[1], collected[2], collected[3])
FROM(Select Array(NULL, 1, NULL, NULL) as collected) a;
这将1
作为COALESCE
函数的第一个非空值返回。然后看到有一个分组函数collect_list(col)
。
因此,如果我们将每个用户7行的输出称为activity_uncollected
,那么您的最终转换将是:
SELECT user_id,
COALESCE(collected_mon[0], collected_mon[1], ..., collected_mon[6]),
...
COALESCE(collected_sun[0], collected_sun[1], ..., collected_sun[6])
FROM
(SELECT user_id,
collect_list(activity_log_mon),
...,
collect_list(activity_log_sun)
FROM activity_uncollected
GROUP BY user_id) a;
将每个用户每天的所有值分组,然后从每个数组中选择非空值。