1

我有一个大的事件表。每个用户我想在最早的 B 类事件之前计算 A 类事件的发生。

我正在寻找一个优雅的查询。使用了 Hive,所以我不能做子查询

Timestamp Type User 
...        A    X
...        A    X
...        B    X
...        A    X
...        A    X

...        A    Y
...        A    Y
...        A    Y
...        B    Y
...        A    Y

想要的结果:

User Count_Type_A 
X    2
Y    3

我无法通过以下方式获得“截止”时间戳:

Select User, min(Timestamp) 
Where Type=B 
Group BY User;

但是,我如何在下一个查询中使用该信息,我想在其中执行以下操作:

SELECT User, count(Timestamp) 
WHERE Type=A AND Timestamp<min(User.Timestamp_Type_B) 
GROUP BY User;

到目前为止,我唯一的想法是首先确定截止时间戳,然后与所有 A 类事件进行连接,然后从结果表中进行选择,但这感觉不对,而且看起来很难看。

我还在考虑这可能是 Hive 的错误类型的问题/分析,我应该考虑手写 map-reduce 或 pig 来代替。

请指出正确的方向来帮助我。

4

2 回答 2

1

第一次更新:

针对 Cilvic 对此答案的第一条评论,我已根据https://issues.apache.org/jira/browse/HIVE-556中的评论中建议的解决方法将查询调整为以下内容:

SELECT [User], COUNT([Timestamp]) AS [Before_First_B_Count]
FROM [Dataset] main
CROSS JOIN (SELECT [User], min([Timestamp]) [First_B_TS] FROM [Dataset]
    WHERE [Type] = 'B'
    GROUP BY [User]) sub 
WHERE main.[Type] = 'A'
AND (sub.[User] = main.[User]) 
AND (main.[Timestamp] < sub.[First_B_TS])
GROUP BY main.[User]

原来的:

试一试:

SELECT [User], COUNT([Timestamp]) AS [Before_First_B_Count]
FROM [Dataset] main
JOIN (SELECT [User], min([Timestamp]) [First_B_TS] FROM [Dataset]
    WHERE [Type] = 'B'
    GROUP BY [User]) sub 
        ON (sub.[User] = main.[User]) AND (main.[Timestamp] < sub.[First_B_TS])
WHERE main.[Type] = 'A'
GROUP BY main.[User]

我尽力遵循 hive 语法。如果您有任何问题,请告诉我。我想知道您为什么希望/需要避免子查询。

于 2012-10-31T20:59:12.513 回答
1

一般来说,我+1 coge.soft 的解决方案。再次供大家参考:

SELECT [User], COUNT([Timestamp]) AS [Before_First_B_Count]
FROM [Dataset] main
JOIN (SELECT [User], min([Timestamp]) [First_B_TS] FROM [Dataset]
    WHERE [Type] = 'B'
    GROUP BY [User]) sub 
        ON (sub.[User] = main.[User]) AND (main.[Timestamp] < sub.[First_B_TS])
WHERE main.[Type] = 'A'
GROUP BY main.[User]

但是,有几点需要注意:

  1. 当没有 B 事件时会发生什么?假设您想要计算每个用户的所有 A 事件,在这种情况下,解决方案中指定的内部联接将不起作用,因为子表中没有该用户的条目。为此,您需要更改为左外连接。

  2. 该解决方案还执行 2 次数据传递 - 一次填充子表,另一次将子表与主表连接。根据您对性能和效率的概念,您可以通过单次数据传递来完成此操作。您可以使用 Hive 的功能分发按用户分发数据,并编写一个自定义减速器,使用Hive 的转换功能以您喜欢的语言进行计数计算。

于 2012-11-01T15:01:09.053 回答