统计小结Part1 | 七日打卡

585 阅读3分钟

统计需求往往能快速提升一个人对业务的熟知,而统计某个指标,本身也是一种衡量的标准。本质上是观察某个现象的水平,好的坏的,高的低的,看多了做多了就能发现数据有没有问题。

再补充下个人理解的统计要素:

1. 统计的指标;比如常用的按时间来统计,这里的时间就是统计的指标;

2. 统计的要素;比如每一天的人数,消耗的金额等,这里的要素就是汇总人数,汇总金额;

进入正文: 以统计某个时间段内每个用户的交易记录为例。

我们利用每一次记录的交易记录表作为统计的标准。

交易记录表数据结构大致为: 

CREATE TABLE `finance_record` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `uid` int(11) DEFAULT '0' COMMENT '用户ID',
  `trade_type` tinyint(1) DEFAULT '0' COMMENT '交易类型 0 充值 1 业务扣款',
  `trade_no` varchar(64) DEFAULT NULL COMMENT '交易号',
  `origin_amount` decimal(11,4) DEFAULT '0.0000' COMMENT '原金额',
  `new_amount` decimal(11,4) DEFAULT '0.0000' COMMENT '新金额',
  `trade_time` datetime(3) DEFAULT NULL COMMENT '交易时间',
  `create_time` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
  `update_time` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trade_no` (`trade_no`)
) ENGINE=InnoDB AUTO_INCREMENT=546 DEFAULT CHARSET=utf8mb4 COMMENT='账户流水';

接下来分析需求,将统计每日流水拆开出来理解就要统计每天每个用户的消耗记录(可能有点生硬)。

针对这种需求,需要有个统计的表数据(区别于上面的明细记录表), 

所以我们生成这张统计表就需要考虑统计的标准,是按天还是按小时或是其他;

生成这个统计记录的任务多久触发一次,要查看的是每一天的历史数据是否还要实时数据; 

统计之后,如果已经统计出来的金额数据发生变动将要如何处理,是替换还是保持不变; 

于是,我们先要定好这个统计表(上面的问题后续再补充解释): 

CREATE TABLE `t_finance_daily_statistics` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `uid` int(11) DEFAULT '0' COMMENT '用户ID',
  `count_time` date DEFAULT NULL COMMENT '统计时间',
  `settle_amount` decimal(11,4) DEFAULT '0.0000' COMMENT '消耗金额',
  `account_new_amount` decimal(11,4) DEFAULT '0.0000' COMMENT '现金账户结余',
  `expect_income` decimal(11,4) DEFAULT '0.0000' COMMENT '预计收入',
  `net_expect_income` decimal(11,4) DEFAULT '0.0000' COMMENT '净收入',
  `create_time` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
  `update_time` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_p_c` (`puid`,`count_time`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8mb4 COMMENT='账户流水日统计数据';

在代码逻辑中遍历每个用户uid,再编辑每一天开始结束时间start, end, 然后在sql中统计每个用户的充值和消耗汇总数据:

sql语句可以这么写: 

select trade_type, sum(`settle_amount`) as `sumSettleAmount` from finance_record where puid = ? and trade_time between ? and ? GROUP BY `trade_type`

 其中 trade_type 0 的是充值, 1的是消耗扣款

利用Collectors.groupingBy得到map分组; 

Map<Integer, List<FinanceRecord>> financeRecordsMap = financeRecords.parallelStream().collect(Collectors.groupingBy(FinanceRecord::getTradeType));

接下来就能够顺利地拿到每一天汇总的充值和消耗数据了,将数据插进汇总表中,大功告成。 至于展示汇总表的需求,就是查表去展示的逻辑了。

明天再分享,谢谢大家!