前言:这是公司的统计需求,需要按全年维度来进行统计
由于统计数据在分布式调度中心做了按月统计和按日统计,并且分别入库到了不同的表里,那么我们只需要根据这两张表来进行统计即可,犹豫数据量过大,所以前11个月的数据需要按照月统计表来进行统计,第十二个月数据不统计当天数据并按日统计表统计。
OK。到这里,我们就可以写查询sql
SELECT
t.dict_value paySources,
IFNULL(c.transcount, 0) transCount,
IFNULL(c.transfee, 0.0) transFee
FROM
sys_dict_data t
LEFT JOIN
(SELECT
CASE a.paysources WHEN '7' THEN 'ls'
WHEN '5' THEN 'hs'
WHEN '0' THEN 'wechat'
WHEN '0' THEN 'alipay'
WHEN '3' THEN 'wowo'
WHEN '6' THEN 'unionpay'
WHEN '4' THEN 'wft'
WHEN '8' THEN 'fubei'
WHEN '9' THEN 'saobei'
WHEN '10' THEN 'ys'
WHEN '11' THEN 'tl'
WHEN '12' THEN 'nyyh'
WHEN '13' THEN 'msl'
WHEN '14' THEN 'sxf'
WHEN '15' THEN 'ebuy'
WHEN '16' THEN 'miya'
WHEN '17' THEN 'ums'
END AS paysources,
SUM(a.transcount) transcount,
SUM(a.transfee) transfee
FROM
business_monthtrans_data a
AND a.transtime BETWEEN #{beginTime} AND #{endTime}
GROUP BY a.paysources) c
ON t.dict_value = c.paysources
WHERE t.dict_type = 'pay_source'
ORDER BY t.dict_sort
这是我的查询sql,一共有两个sql,我这里只写一个,上文说到,查询的是月统计表和日统计表,犹豫两张表里的字段是一样的,所以我们只放了一条sql上来,另一条换一个表名罢了!!
那么接下来看一下查询到的数据
现在问题来了! 两张表的数据都是上图的这个样式,而我现在需要返回前11个月的数据+12月份的数据的前一天(当天不纳入统计),怎样才能做到?
首先来看看我的代码
@Override
@DataScope(tableAlias = "t1")
public String queryBusinessYearTransDataTra(BusinessDaytransData businessDaytransData)
{
Map map = new HashMap();
Map mapto = new HashMap();
HashMap hashMap = new HashMap<>();
List list = new ArrayList<>();
// 查询前12月交易 按月统计数据
String beginTime = DateUtils.getLastMouthDayForYear(); //获取本月 前12个月 的最初月份
String endTime = DateUtils.getDayLastOfMonth(); //获取上月的最后一天 当月数据不纳入统计当中
map.put("beginTime", beginTime);
map.put("endTime", endTime);
map.put("dataScope", businessDaytransData.getParams().get("dataScope"));
String firstDayOfMonth = DateUtils.getFirstDayOfMonth();//获取当月的第一天
String beforeDay = DateUtils.getBeforeDay(1); //获取当前天的前一天
mapto.put("beginTime", firstDayOfMonth);
mapto.put("endTime", beforeDay);
mapto.put("dataScope", businessDaytransData.getParams().get("dataScope"));
//查出前11月份的数据
List businessByEffectiveMoth = detailInfoOnMapper.queryByEffectiveAmountPayMonth(map);
//拿当前日期前一天的本月数据
List businessByEffectiveLastMoth = businessDaytransDataMapper.queryEachDayToatalDataListTra(mapto);
这里明确可以看到,我写到了2个mapper,分别用来查询余月统计表和日统计表,前面的map里封装了查询的条件(时间),那么我们得到了两个查询的结果,分别是businessByEffectiveMoth 和businessByEffectiveLastMoth 。
现在回过头来看我们得统计全年,可以看到报表上永远只展示一个封装好的对象,而不是两个,
所以我们要将这两个查询出来的list相加,由于paySources支付通道的这个字段是一致的,而剩余的两条transCount和transFee,我们要给它加起来:类似于BigDecimal a = businessByEffectiveMoth.gettransCount + businessByEffectiveLastMoth.getgettransCount
BigDecimal b =businessByEffectiveMoth.gettransFee+ businessByEffectiveLastMoth.getgettransFee
兄弟们,开动一下你们的头脑,给出一个方案!!!!!
解决办法:代码展示
//查出前11月份的数据
List businessByEffectiveMoth = detailInfoOnMapper.queryByEffectiveAmountPayMonth(map);
//拿当前日期前一天的本月数据
List businessByEffectiveLastMoth = businessDaytransDataMapper.queryEachDayToatalDataListTra(mapto);
BusinessValue businessValue = null;
for (int i = 0; i < businessByEffectiveMoth.size(); i++)
{
BusinessByEffectiveAmount businessByEffectiveAmount = businessByEffectiveMoth.get(i);
String paySourcesfirst = businessByEffectiveAmount.getPaySources();
BigDecimal transFee = businessByEffectiveAmount.getTransFee();
Long transCount = businessByEffectiveAmount.getTransCount();
businessValue = new BusinessValue();
businessValue.setTranscount(new BigDecimal(transCount));
businessValue.setTransfee(transFee);
hashMap.put(paySourcesfirst, businessValue);
}
for (int i = 0; i < businessByEffectiveLastMoth.size(); i++)
{
BusinessByEffectiveAmount businessByEffectiveAmount = businessByEffectiveLastMoth.get(i);
String paySourceslast = businessByEffectiveAmount.getPaySources();
BusinessValue value = hashMap.get(paySourceslast);
BigDecimal transCountMonth = new BigDecimal(businessByEffectiveAmount.getTransCount());
BigDecimal transcountlastMonth = value.getTranscount();
value.setTranscount(transcountlastMonth.add(transCountMonth));
BigDecimal transFeelastMouth = businessByEffectiveAmount.getTransFee();
BigDecimal transFeeMouth = value.getTransfee();
value.setTransfee(transFeeMouth.add(transFeelastMouth).setScale(2,BigDecimal.ROUND_DOWN));
}
BigDecimal count = new BigDecimal(0);
//求总笔数
Iterator iter = hashMap.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
BusinessValue value = hashMap.get(key);
BigDecimal transcount = value.getTranscount();
count = count.add(transcount);//总笔数
businessValue.setTranscountSum(count);
}
list.add(businessValue);
list.add(hashMap);
//对两个集合 求和
return JSON.toJSONString(list);
首先我遍历了月统计表的list,从里面将查出来的值分别取出(很明显),然后我new hashMap
和一个 BusinessValue 对象。hashMap的Key用来存他们相同的的字段,也就是paySources支付通道,而value则用来存储BusinessValue对象 。来看一下BusinessValue的属性。
package com.ruipos.transaction.domain;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class BusinessValue
{
private BigDecimal transfee;
private BigDecimal transcount;
private BigDecimal transcountSum; //总笔数
}
回过头来,此时将月统计表的数据存到了map里,然后再遍历日统计表,来取里面的数据,日统计表循环里有这么一行代码非常有意思:上面我们说了,他们的key是一样的,于是我把日统计表里取到的paySourceslast做为条件放进了月统计表里的hashMap的key里
BusinessValue value = hashMap.get(paySourceslast);
然后去取里面的value值,对它们相加再塞回value里,最终hashmap的值就会是这样的
key它还是那个key,但是里面的值已经相加了。
最终遍历hashmap,去取transcout(总笔数) ,并给它累加,一起放到一个List当中通过
JSON.toJSONString(list)转换成一个字符串,返回给了前端。
兄弟们!!如果你们有更秒的办法,请在留言区说出你的答案!!!!!!