BigQuery日志文件中每个用户的最新事件

时间:2014-05-23 07:16:14

标签: google-bigquery

这一定很简单但是让我难以置信于BQ

简单日志文件:

mysql> select * from wow;
+------+---------------+------------+
| id   | string        | epoch      |
+------+---------------+------------+
| id3  | a new user    | 1400783480 |
| id1  | a log event 1 | 1400783492 |
| id1  | a log event 2 | 1400783499 |  
| id1  | a log event 3 | 1400783503 |
| id2  | a log event 1 | 1400783510 |
| id2  | a log event 2 | 1400783516 |
+------+---------------+------------+

我想在BQ中执行等效操作以查找每个Id的最后一个事件:

mysql> select * from (select * from wow as B order by epoch desc) as A group by id;
+------+---------------+------------+
| id   | string        | epoch      |
+------+---------------+------------+
| id1  | a log event 3 | 1400783503 |
| id2  | a log event 2 | 1400783516 |
| id3  | a new user    | 1400783480 |
+------+---------------+------------+
3 rows in set (0.00 sec)

任何提示/帮助都非常感激。

2 个答案:

答案 0 :(得分:2)

最简单的方法可能是使用GROUP BYMIN进行查询,找到您想要的(id, epoch)对,然后将其加入原始表:

SELECT t.*
FROM 
    (SELECT id, MAX(epoch) AS max_epoch FROM [tmp.so1] GROUP BY id) AS keys 
  JOIN 
    [tmp.so1] AS t 
  ON keys.id = t.id AND keys.max_epoch = t.epoch 
ORDER BY t.id

对于您的数据,这确实给出了回复:

+------+---------------+------------+
| t_id |     t_msg     |  t_epoch   |
+------+---------------+------------+
| id1  | a log event 3 | 1400783503 |
| id2  | a log event 2 | 1400783516 |
| id3  | a new user    | 1400783480 |
+------+---------------+------------+

三个注释:

  • 我使用方便的t.*简写作为结果,但如果你想要原始名称,你可以实际映射它们
  • 如果您的桌子变大,您可能想要切换到JOIN EACH
  • 如果您有多个具有给定ID的最小纪元的条目,您将获得加倍的行。

答案 1 :(得分:1)

我宁愿避免加入,因为有更优雅的方法可以做到这一点:

  1. 如果您的数据集不是太大,请使用rownumber():

    选择* 从 (选择*,row_number()over(由epoc desc按id顺序划分)作为RNB 从T) 其中RNB = 1

  2. 对于较大的数据集,您可以操作max(时间)和日志字符串来为每个用户填写最后一个日志条目。

    从id组中选择id,substring(max(concat(string(epoch),logstring)),10)

  3. 希望这有帮助。