项目中用sql实现一个导购下所拥有客户的订单总数,返回订单数和导购id

本文探讨了如何修复一个关于通过Redis存储和计算部门级导购订单的bug,涉及批量取数据、订单量计算公式以及MyBatis中的SQL映射。作者详细介绍了问题排查过程和最终的解决方法,确保了正确地按部门汇总订单数。
摘要由CSDN通过智能技术生成

有个bug是关于图表数据统计,导购数据没问题,部门数据计算不正确
因为数据按照一个导购来算,所以设计上把一个导购存入redis一个hash key,取部门的情况下需要批量取hash中的key,金额公式大致为导购下所有客户的订单金额/订单数,因为取出来的是计算好的结果,所以为了算部门下所有导购,需要做乘订单求和再除总订单的情况
总关系如下,即部门-导购-员工-订单

关键在于agent_id作为导购id,旗下客户为member_id,则可以得到下面的sql,agent_id分组,则能算出旗下订单数

SELECT a.agent_id , count(o.member_id) as orderCount
FROM orders o 
INNER JOIN  
(
	SELECT member_id,agent_id from member_analysis WHERE agent_id in (12887,13083)
) a on o.member_id = a.member_id
WHERE o.member_id 
in(
SELECT member_id
FROM `member_analysis`
where agent_id in (12887,13083)
)
and pay_status='PAY_FINISH'
GROUP BY agent_id

mapper,用到的两个in全部传自同一个传参,注意进方法前一定要判空,这里mybatis没做判空处理

@Select("<script>" +
            "SELECT a.agent_id , count(o.member_id) as orderCount\n" +
            "FROM orders o \n" +
            "INNER JOIN  \n" +
            "(" +
            "SELECT member_id,agent_id from member_analysis WHERE agent_id in <foreach item='item' index='index' collection='agentIds' open='(' separator=',' close=')'>" +
            "#{item}" +
            "</foreach>" +
            ") a on o.member_id = a.member_id\n" +
            "WHERE o.member_id \n" +
            "in(" +
            "SELECT member_id\n" +
            "FROM `member_analysis`\n" +
            "where agent_id in <foreach item='item' index='index' collection='agentIds' open='(' separator=',' close=')'>" +
            "#{item}" +
            "</foreach>" +
            ")" +
            "and pay_status='PAY_FINISH'\n" +
            "GROUP BY agent_id" +
            "</script>")
    List<MemberCountAndAgentVO> getOrderCountWithAgentId(@Param("agentIds") List<String> agentIds);

service使用
先判空,拿到list

List<MemberCountAndAgentVO> orderCountAndAgentlist = new ArrayList<>();
if (ObjectUtil.isNotEmpty(memberIds)){
	orderCountAndAgentlist = memberAnalysisMapper.getOrderCountWithAgentId(memberIds);
}

聚合成map,key为导购id,value为订单数量,算出总订单数作为分母

Map<String, Object> orderCountAndAgentMap = orderCountAndAgentlist.stream().collect(Collectors.toMap(MemberCountAndAgentVO::getAgentId, MemberCountAndAgentVO::getOrderCount, (k1, k2) -> k1));
Integer orderCount = orderCountAndAgentlist.stream().collect(Collectors.summingInt(MemberCountAndAgentVO::getOrderCount));
orderCount = orderCount == 0 ? 1 : orderCount;

进循环,遍历累加,先判断传进来的实体类id要一一对应

if (orderCountAndAgentMap.containsKey(portraitVO.getMemberId())){
	Integer orderOldCount = Integer.parseInt(orderCountAndAgentMap.get(portraitVO.getMemberId()).toString());
	customerUnitPriceDouble = Double.parseDouble(portraitVO.getCustomerUnitPrice()) * orderOldCount;
}
customerUnitPrice = customerUnitPrice.add(BigDecimal.valueOf(customerUnitPriceDouble));

在循环外做除法

customerUnitPrice = customerUnitPrice.divide(BigDecimal.valueOf(orderCount),4,BigDecimal.ROUND_HALF_UP);

最终返回结果

在这里插入图片描述
计算出来是正确的,完美
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值