这个思路针对排行榜,好久没上榜装高手了,我好想上榜装高手啊

统计方式(以伤害榜为例)

统计的伤害每天删除一次,删除前作玩家伤害排序(不保存),排序后有如下积分转换(并列同分):
top41到50:1
top31到40:3
top21到30:5
top16到20:9
top11到15:13
top6到10:23→21→19→17→15
top1到5:42→39→36→33→30

这些积分会保留一周,到周结算时根据周内每日积分的和再进行排榜(公布,下一周榜更新时删除原周榜及周内总积分数据),排榜后得出周积分,周积分会保留一个月,以此类推得出月榜(仍每月更新并删除旧榜),月榜转换积分(该积分保留一年)叠加计算季度榜、年榜(这两个榜单永久保留)

榜单奖励(部分榜单)

季度、年
top41到50:0、90
top31到40:40、120
top21到30:50、150
top11到20:60、180
top6到10:100、300
top1到5:200、600

部分季度榜、年榜换算积分后将按一定权重叠加后换算成rating(综合评分,范围0到2)(rating榜积分奖励翻倍)

部分榜单的原因:如钉子榜(如果有的话)可能存在水钉(整理素材钉、一材多钉、多余素材刷钉等),可能需要特殊处理;又如复活榜(假如未来还有的话)这种相对娱乐性更强的榜单也不发奖励

以上奖励看起来不如连续签到来得多,但是榜类型多样且统计到top50(不难上榜),实际上还可以

排行展示拓展

①在个人界面内显示各项数据的雷达图:以月积分为依据折算成0到2的评分指数,该月指数保留一年,转换的季度和年指数可永久保留以查看历史雷达图,同时计算对应时期的top50平均雷达图,雷达图显示效果参考:

还有一个非雷达图的ui思路,显示效果也不错:

②各年榜单前5及总榜前20获得对应奖牌(以对应图标在个人界面展示,永久保存),除前3外图标均为铜色,前三分别为银色、金色、榜单代表色(也可以是除前3外白色,前3铜银金);奖牌显示效果参考标红部分:

什么真搞排行榜啊,那我深夜偷偷玩bug岂不是会被发现(

DROP TABLE IF EXISTS rhd_ods_damage_inc_1d;
CREATE TABLE rhd_ods_damage_inc_1d
(
    `event_id`  STRING ,
    `steam_id`  STRING ,
    `weapon_id` STRING ,
    `map_id`    STRING ,
    `zombie_id` STRING ,
    `body_area` STRING ,
    `buff_list` STRING ,
    `damage`    DECIMAL(16 , 2) ,
    ts          STRING comment "2024-05-06 23:15:32 982"
) COMMENT '原始伤害表'
    partitioned by (`dt` string comment '统计日期')
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/rhd/ods/damage_inc_1d';

DROP TABLE IF EXISTS rhd_dwd_damage_inc;
CREATE TABLE rhd_dwd_damage_inc
(
    `steam_id` STRING ,
    `damage`   DECIMAL(16 , 2)
) COMMENT '伤害表'
    partitioned by (`dt` string comment '统计日期')
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/rhd/dwd/damage_inc_1d';

DROP TABLE IF EXISTS rhd_dws_damage_inc_1d;
CREATE TABLE rhd_dws_damage_inc_1d
(
    `steam_id`   STRING ,
    `sum_damage` DECIMAL(16 , 2)
) COMMENT '1日伤害表汇总表'
    partitioned by (`dt` string comment '统计日期')
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/rhd/dws/damage_inc';
DROP TABLE IF EXISTS rhd_dws_damage_inc_nd;
CREATE TABLE rhd_dws_damage_inc_nd
(
    `steam_id`    STRING ,
    `sum_damage`  DECIMAL(16 , 2) ,
    `recent_days` TINYINT COMMENT '最近天数: 1,7,30,90,365'
) COMMENT '1日伤害表汇总表'
    partitioned by (`dt` string comment '统计日期')
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
        NULL DEFINED AS ''
    LOCATION '/warehouse/rhd/dws/damage_inc';

insert overwrite table rhd_dwd_damage_inc partition
    (
        dt = "2024-08-05"
    )
select
    steam_id
  , damage
    from rhd_ods_damage_inc_1d
    where
        dt = "2024-08-05";

insert overwrite table rhd_dwd_damage_inc_1d partition
    (
        dt = "2024-08-05"
    )
select
    steam_id
  , sum( damage )
    from rhd_dwd_damage_inc
    where
        dt = '2024-08-05'
    group by
        steam_id;
insert overwrite table rhd_dws_damage_inc_nd partition
    (
        dt = "2024-08-05"
    )
select
    steam_id
  , sum( sum_damage )
  , recent_day
    from
        (
            select *
                from rhd_dws_damage_inc_1d lateral view explode( array( 1 , 7 , 30 , 90 , 365 ) ) tmp as recent_day
        ) t1
    where
        dt between date_sub( "2024-08-05" , recent_day - 1 ) and "2024-08-05"
    group by
        steam_id
      , recent_day

之后定期清空ODS的1日数据表和 DWD的明细表就可以了,只要每日执行上面的SQL 改一改dt就可以完成伤害的1日7日30日90日365日数据统计,如果统计指标比较简单 可以直接把 dws的nd表删掉,提高到应用层

这是HQL语法!

    统计出来的数据是相对于原始数据是很小的,一个人一天哪怕有上百万条伤害记录最后统计出来就只有一条统计数据
    如果将口径放大到1、7、30、90、365,也只是变成了5条数据,所以统计数据是不用删的
    大头是原始数据就是每一次输出如果造成伤害就会有一条统计数据,如果对多个目标造成伤害就会同时产生多条统计数据
    统计数据可能包含 什么人用了那把枪使用了哪些buff 处于什么状态在那张地图,那个位置以什么方式对那个僵尸的那个部位造成了多少伤害,所以原始数据就会很大。

    当然以上差不多是最小粒度的统计,如果放大统计粒度数据也不会这么多,我之前写的SQL也没有那么细

      Duang已经 8天,215个小时,12927分钟,775665秒没有理我了

      目前没有人在打字