我认为将每个游戏的所有玩家放在一个分区中可能会更容易。
这样您就可以用一个查询聚合所有玩家,而不是为每个玩家单独查询。然后,您可以将每个玩家的游戏时间汇总到一张地图中(请参阅如何为 here 定义 UDF 的示例)。
所以你的表格看起来像这样:
CREATE TABLE playing_time_by_game (game_id text, event_time int, player_id text, amount_played int, PRIMARY KEY (game_id, event_time));
然后根据 player_id 创建 UDF:
CREATE FUNCTION state_group_and_total( state map<text, int>, type text, amount int )
CALLED ON NULL INPUT
RETURNS map<text, int>
LANGUAGE java AS '
Integer count = (Integer) state.get(type); if (count == null) count = amount; else count = count + amount; state.put(type, count); return state; ' ;
然后创建聚合函数:
CREATE OR REPLACE AGGREGATE group_and_total(text, int)
SFUNC state_group_and_total
STYPE map<text, int>
INITCOND {};
然后插入一些数据:
SELECT * from playing_time_by_game ;
game_id | event_time | amount_played | player_id
---------+------------+---------------+-----------
game1 | 0 | 8 | player1
game1 | 1 | 12 | player2
game1 | 5 | 1 | player2
game1 | 8 | 50 | player1
game2 | 0 | 200 | player1
现在您可以按 player_id 聚合:
SELECT group_and_total(player_id, amount_played) from playing_time_by_game;
t2.group_and_total(player_id, amount_played)
----------------------------------------------
{'player1': 258, 'player2': 13}
并且可以将查询限制在游戏分区和时间范围内:
SELECT group_and_total(player_id, amount_played) from playing_time_by_game where game_id='game1' and event_time >=0 and event_time <=7;
t2.group_and_total(player_id, amount_played)
----------------------------------------------
{'player1': 8, 'player2': 13}
您可能还可以定义一个 FINALFUNC 来排序并仅保留地图中的前十项。见this。