Hive 配置单元QL-基于条件选择,分组在一行上

Hive 配置单元QL-基于条件选择,分组在一行上,hive,hiveql,Hive,Hiveql,我有一个日期分区的配置单元表,每个用户有一行。它有一个列activity_log,其值为1或0,具体取决于用户是否在该日期执行该活动 我还有一个UDF,比如dayOfWeek,它给了我一周中的某一天一个日期 我正在尝试创建一个表,其中包含过去一周的用户活动。因此,列将是: user, activity_log_mon, activity_log_tue, activity_log_wed, ...activity_log_sun 每个activity_log列的值应为1或0,指示用户是否在上周

我有一个日期分区的配置单元表,每个用户有一行。它有一个列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'
我实际想要的是一个表,每个用户只有一行,如下所示:

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

我怎样才能像这样重新组合行?或者,首先获得这样的行的最佳方法是什么

观察以下HiveQL的行为:

SELECT COALESCE(collected[0], collected[1], collected[2], collected[3]) 
FROM(Select Array(NULL, 1, NULL, NULL) as collected) a;
这将返回1作为COALESCE函数的第一个非空值。然后看有一个分组函数collect\u listcol

因此,如果我们将每个用户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;

这会对每个用户每天的所有值进行分组,然后从每个数组中选取非空值。

下面是我最后要做的:

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

我正在考虑使用COALESCE,但我不知道如何使用。实际上,我最后做的是将未收集的activity_列相加,按用户分组。