用户行为分析系列实践 2 - 冗余分组键

目标任务

用户事件表T结构和部分数据示例如下:

Time UserID EventTypeID EventType
2022/6/1 10:20 1072755 3 Search
2022/6/1 12:12 1078030 2 Browse
2022/6/1 12:36 1005093 5 Submit
2022/6/1 13:21 1048655 1 Login
2022/6/1 14:46 1037824 6 Logout
2022/6/1 15:19 1049626 4 AddtoCart
2022/6/1 16:00 1009296 5 Submit
2022/6/1 16:39 1070713 2 Browse
2022/6/1 17:40 1090884 3 Search

T表字段说明:

字段名 数据类型 字段含义
Time 日期时间 事件发生的时间戳,精确到毫秒
UserID 整数 用户ID
EventTypeID 整数 事件类型ID
EventType 字符串 事件类型名称

计算任务:

统计指定时间段内每种事件类型下的发生次数和发生过该事件的去重用户数,结果需要显示事件类型的名称。

在生成宽表时,为减少 JOIN 运算,经常会把代码字段和值字段都生成出来,而值字段可以被代码字段唯一决定。具体在这里就是,在期望的查询时间段内,事件类型的名称完全可以由事件类型ID决定。

实践技能

冗余分组键:当多个分组键中有一些能被另一些决定时,可以只按起决定作用的字段分组,被决定的字段直接取出第一个值,不再参与分组,计算性能更优。

比如本例:事件类型名称完全由事件类型ID决定,这种情况可以只按事件类型ID分组,对事件类型名称直接取出第一个值即可。

示例代码

设统计时间段为2022315日到2022616日:


A
1 =file("T.btx").cursor@mb()
2 >start=date("2022-03-15","yyyy-MM-dd"),end=date("2022-06-16","yyyy-MM-dd")
3 =A1.select(Time<=end && Time>=start).groups(EventTypeID; EventType, count(1):Num, icount(UserID):iNum)

groups函数中写在分号前面的是分组字段EventTypeID,由于EventTypeEventTypeID决定,所以把EventType写在汇总表达式部分,但不写聚合运算,就表示直接取出本组的第一个成员。这个字段不再参与分组比对,计算性能更好。

分组字段必须选择起决定作用的字段,而被决定的字段写到分号后面,不能反了。

运行结果:

EventTypeID EventType Num iNum
1 Login 4033000 393400
2 Browse 3578901 348791
3 Search 2947931 257539
4 AddtoCart 1845674 175476
5 Submit 867345 83375
6 Logout 4033000 393400