HIVE 使用列作为索引和聚合作为值构造 ARRAY
HIVE constructing ARRAY using a column as index and an aggregate as value
我有一个 table 有 ip,session_id,小时。
我想汇总这些数据并以一个新的 table 结束,其中每个 ip 都有一条记录,其中包含每小时汇总的会话数数组。
为此,我从子查询开始,
SELECT ip, count(session_id) as sessions, hour
FROM current_table
GROUP BY ip,hour;
这将为每个 ip 提供(最多)24 条记录,并在相应记录中显示特定小时内的会话数。使用此子查询,我想填充一个数组(比如 hourly_sessions 是我正在使用的数组),如
hourly_sessions[hour] = sessions
所以我最终会得到一个与每个 ip 关联的数组,数组索引代表我要检查会话聚合的时间。如果在特定时间没有会话,我希望它显示 0。
如何在 HIVE 中使用 UDF 实现此 with/without?
我目前的(hacky 和不完整的)方法是使用类似的东西:
collect_set(concat_ws(",",hour,cast(sessions) as STRING))
但这需要在每次需要特定的小时聚合时解析整个数组。
首先,我认为您需要了解如何填补数据中的任何空白。在 (ip, hour) 对方面。一种方法是创建 table 小时数:
CREATE TABLE HOURS AS Select explode(Array(0,1,2...,23)) as hour;
然后 table 不同的 IPS:
CREATE TABLE IPS AS SELECT distinct ip from current_table;
然后加入他们:
CREATE TABLE IP_HOURS AS SELECT IPS join HOURS;
这为每个 IP 提供了 23 个条目。加入您的实际计数:
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)
您可以按原样使用此 table,但如果您真的想将每小时的计数压缩到一个数组中以便每个 ID 有一行,您可以使用 Brickhouse "Collect" UDF ,因为它将维护会话计数的顺序,如果您按 ip 排序数据,则小时优先。内置 Hive collect_set 不保证保留顺序。
我有一个 table 有 ip,session_id,小时。 我想汇总这些数据并以一个新的 table 结束,其中每个 ip 都有一条记录,其中包含每小时汇总的会话数数组。
为此,我从子查询开始,
SELECT ip, count(session_id) as sessions, hour
FROM current_table
GROUP BY ip,hour;
这将为每个 ip 提供(最多)24 条记录,并在相应记录中显示特定小时内的会话数。使用此子查询,我想填充一个数组(比如 hourly_sessions 是我正在使用的数组),如
hourly_sessions[hour] = sessions
所以我最终会得到一个与每个 ip 关联的数组,数组索引代表我要检查会话聚合的时间。如果在特定时间没有会话,我希望它显示 0。
如何在 HIVE 中使用 UDF 实现此 with/without? 我目前的(hacky 和不完整的)方法是使用类似的东西:
collect_set(concat_ws(",",hour,cast(sessions) as STRING))
但这需要在每次需要特定的小时聚合时解析整个数组。
首先,我认为您需要了解如何填补数据中的任何空白。在 (ip, hour) 对方面。一种方法是创建 table 小时数:
CREATE TABLE HOURS AS Select explode(Array(0,1,2...,23)) as hour;
然后 table 不同的 IPS:
CREATE TABLE IPS AS SELECT distinct ip from current_table;
然后加入他们:
CREATE TABLE IP_HOURS AS SELECT IPS join HOURS;
这为每个 IP 提供了 23 个条目。加入您的实际计数:
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)
您可以按原样使用此 table,但如果您真的想将每小时的计数压缩到一个数组中以便每个 ID 有一行,您可以使用 Brickhouse "Collect" UDF ,因为它将维护会话计数的顺序,如果您按 ip 排序数据,则小时优先。内置 Hive collect_set 不保证保留顺序。