上周做了一个订单数据统计的任务。统计数据是订单中的新客户数量。本文记录并整理了解题过程。新客户的定义新客户是指在选择的时间段内有订单,但在该时间段之前没有订单。例如下面的订单数据:2月1日之前,2月1日到3月1日,客户A、B、CA、D、E在2月1日之前分别有A、B、C3家公司的订单,而2月1日至3月1日,A、D、E公司下单,发现2月1日至3月1日存在但2月1日前不存在的客户,即D、E公司只是新客户。订单表t_order有如下字段:标识id,订单号order_sn,业务员sales,客户公司,order_time统计某段时间新客户的数量(难易:简单)比如统计2月1日到3月1日对于新客户,时间段的开始时间和结束时间分别用begin和end表示。先统计2月1日之前的客户数,用groupby做去重处理:selectcompanyfromt_orderwhereorder_time=beginandorder_time<=endgroupbycompany2月1号到3月1号有新客户,2月1号之前没有客户,也就是2月1号到3月1号去掉2月1号之前的客户,整合上面两条sql获取以下sql的语句:selectcount(*)from(selectcompanyfromt_orderwhereorder_time>=beginandorder_time<=endgroupbycompany)wherecompanynotin(selectcompanyfromt_orderwhereorder_time=beginandorder_time<=endgroupbycompany,sales上图显示了时间段和时间段之前的客户,相同的客户通过关联联系起来。其中,无关的为新客户,即C为新客户。连接两个查询,然后用salesman做分组查询,就可以得到每个商家的新客户数:selecttoi1.sales,sum(if(toi1.companyisnotnullandtoi2.companyisnull,1,0))作为新客户from(selectcompany,salesfromt_orderwhereorder_time>=beginandorder_time<=endgroupbycompany,sales)toi1leftjoin(selectcompanyfromt_orderwhereorde)r_time=beginandorder_time<=endgroupbysubstring(order_time,1,#{subTime})第2步:统计每天之前的客户数。每天都需要和之前的数据进行比较。首先查询每天的客户集合,遍历每天的数据,然后查询之前的数据。如果当前客户不是以前的客户,则为新客户。因为查询需要多次查询,所以查询时间会很长。例如查询2月1日到2月3日的新客户:|日期|公司合集||:-----:|:----:||2月1日|一个,乙||2月2日|乙,乙||2月3日|C、E|上面有3条数据,查询要循环3次。如果时间段较长,则查询时间会更长。后来想到用unionall组合查询。在上述查询的基础上,使用foreach遍历每条数据,每条数据向前查询客户的数据集合:选择#{list.order_time}作为order_time,group_concat(distinct(company))作为来自t_order_info的公司whereorder_type=1andamount>0andfinish_subtypenotin(3,6)andsubstring(order_time,1,#{subTime})<#{list.order_time}和#{company}上面的sql其实应该是这样的格式:selectorder_time,companyfromt_orderunionallselectorder_time,companyfromt_orderunionallselectorder_time,companyfromt_orderuseunionall联合查询,这样会快很多。步骤3:步骤1的采集去掉步骤2采集的时间段包含的数据,去掉之前的采集,也就是新客户。group_concat拼接字符会不完整,这是因为超过了group_concat_max_len的值,默认是1024,增大该值即可。方案二:升级方案以下是2月1日之前和2月1日-2月3日客户合集:|日期|2月1日之前|2月1日|2月2日|2月3日||:----:|:----:|:----:|:----:|:----:||公司|A,B|C|A,D|C,D|分析先看2月1日的数据。2月1号之前客户C不存在,所以2月1号新增的客户是C。然后查看2月2号找到2月2号之前的数据。2月2号之前就是2月1号之前+2月1号,所以2月2号之前的数据确实不需要去数据库查询,积累以前的数据。该解决方案使用set集合来存储数据。首先将2月1日之前的数据放入集合中,将A和B放入2月1日之前的集合中,如果集合不存在,则为新客户。首先,2月1日的C不在集合中,所以2月1日的新客户是C。然后将C添加到集合中。2月2日的A在集合中,D不在集合中,所以2月2日的新客户是D。将D加入集合中。2月3日的C和D都在集合中,所以2月3日没有新客户。如果您觉得文章对您有帮助,请点个赞吧!