Java多表关联查询的一种解决方案

问题痛点:

不妨假设有如下三个表:

A表     

aidnumber
anamevarchar(100)
aweightnumber

B表     

bidnumber
bnamevarchar(100)
bweightnumber

C表     

cidnumber
cnamevarchar(100)
cweightnumber

我们需要如下查询语句:

select * from A full join B on a.aid = b.bid full join C on a.aid=c.cid

由于使用full join所以肯定存在A表有数据B表没有数据或者B表有数据A表没有数据的情况。

如果我们希望A表有数据时取A的aid,如果A没有数据取B的bid,如果A、B表都没有数据取C表的cid

此处一般需要采用case when等语句进行处理。

现在欲在代码层面进行处理,同时避免full join语句

1.SQL语句改为:

select 1 as num, A.aid, A.aname as n,A.aweight as amount from A
union all
select 2 as num, B.* from B
union all
select 3 as num, C.* from C

语句查询后出现记录应该有:

numaidnamount备注
11000测试12A表记录
21000测试123B表记录
31000测试2344C表记录

............

List<Map<String, Object>> middleChangeList = resultList.stream().map(x -> {
            Long num = (Long) x.get("num");
            x.put("n" + num, x.get("n"));
            x.put("amount" + num, x.get("amount"));
            x.remove("num");
            x.remove("n");
            x.remove("amount");
            return x;
        }).collect(Collectors.toList());

经过上面转换后变为:

aid: 1000    n1:测试    amount1:12

aid:1000     n2:测试    amount2:123

aid:1000     n3:测试    amount3:2344

............

//结果集合并
Set<String> set = new HashSet<String>();
resultList = middleChangeList.stream().collect(Collectors.groupingBy(o -> {
        // 暂存所有key
        set.addAll(o.keySet());
        for (int index = 1; index < 4; index++) {
            set.add("n" + index);   //方便对没有数据的记录补0
            set.add("amount" + index);  //方便对没有数据的记录补0
        }
        return o.get("aid");
})).entrySet().stream().map(o -> {
        // 合并
        Map<String, Object> map = o.getValue().stream().flatMap(m -> {
            return m.entrySet().stream();
        }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));
        // 为没有key的赋值0
        set.stream().forEach(k -> {
            if (!map.containsKey(k))
                map.put(k, 0);
        });
        return map;
}).sorted((map1, map2) -> {
        return map1.get("aid").toString().compareTo(map2.get("aid").toString());  //根据aid进行排序
}).collect(Collectors.toList());        

经过上面转换后:

aid:1000   n1:测试     amount1:12    n2:测试    amount2:123   n3:测试    amount3:2344

........................................

此时基本达到要求了。

提高:

添加每一列合计代码:

Map<String,Object> totalMap = new HashMap<String, Object>();
for (int index = 1; index < 3; index++) {
      final int dIndex = index;   
      totalMap.put("amount" + index, resultList.stream().collect(Collectors.summingDouble(
            	    e -> Double.parseDouble(e.get("amount" + dIndex).toString()))));
}
totalMap.put("topic", "总计");
//添加合并结果集
resultList.add(totalMap);	

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值