报表如何实现多表联查原创
金蝶云社区-陈来珍
陈来珍
0人赞赏了该文章 1,755次浏览 未经作者许可,禁止转载编辑于2023年10月16日 11:22:25
summary-icon摘要由AI智能服务提供

本文讨论了在一个需要查询采购入库单和生产入库单实时数据量的报表系统中,面对大数据量和实时性要求时的解决方案。通过创建中间表并利用定时任务处理数据,以提高查询效率。文章详细描述了创建中间表、配置定时任务、编写调度任务类及主业务计算逻辑等步骤,实现了将原始数据定期汇总至中间表,以便报表快速查询。最后,展示了通过调度任务执行后,中间表已正确插入数据的效果图,并附带了开发环境版本和参考资料。

关键词:报表、中间表、多表联查

一、需求

1、原始需求:在报表查询时,要求查询出采购入库单和生产入库单当日和当月各个仓库各个物料对应的入库数量,如下:

仓库物料本日采购入库数量本月采购入库数量本日生产入库数量本月生产入库数量
华南仓库摸具111333111222

表单信息如下:

image.png

image.png


二、思路与方案

1、痛点分析:后续可能有上千万条数据多表联查处理,始时查询的报表很慢,并且采购入库和生产入库的业务单每秒中都可能产生,所以综合考虑下:

(1)数据量大,查询慢

(2)实时性要求不了

那么可以通过创建中间表、用定时任务在某个时间间隔时处理好相关数据并插入中间表,然后报表可以直接取数。

2、开发方案

本案例只接受插入中间表的过程

image.png

三、实现过程

1、创建中间表

image.png


2、定时任务配置

配置过程参考:https://developer.kingdee.com/school/144893020511528192?productLineId=29

3、编写调度任务类

public class ImTaskCountScheduler extends AbstractTask {
//    public TaskImCountScheduler() {
//    }
//调度任务执行入口
    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
        //任务处理逻辑另起接口,方便其他地方直接调用
        ImTaskCountService taskCountService = new ImTaskCountServiceImpl();
        taskCountService.countTask();
    }
}

主业务计算逻辑(详细代码看文章后面的附件)

//实现中间表数据存储功能
@Override
public void countTask() {
    ImDateRangeEnum[] dateRangeEnums = ImDateRangeEnum.values();
    DataSet preDS=null;
    //计算各个表单的数据
    for (int index = 0; index < BILLNUMBER.length; index++) {
        //(1)查出某表单本日数据
        DataSet taskdData = this.query(dateRangeEnums[0], BILLNUMBER[index]);
        //(2)查出某表单本月数据
        DataSet taskmData = this.query(dateRangeEnums[3], BILLNUMBER[index]);
        if (taskdData == null || taskmData == null) {
            logger.info("待同步数据为空");
            return;
        }
        //今天数据分组求和
        taskdData = this.process(taskdData);
        //本月数据分组求和
        taskmData = this.process(taskmData);
        //(3)本日数据和本月数据合并,以月份数据为主表,因为本日存在的仓库、物料对应的入库数据,本月数据中一定有
        DataSet billDs = taskdData.rightJoin(taskmData).on(groupBy[0], groupBy[0]).on(groupBy[1], groupBy[1]).
                select(new String[]{ "qty" + " as " + TARGET_QTY[index][0]},
                        new String[]{groupBy[0], groupBy[1],"qty" + " as " + TARGET_QTY[index][1]}).finish();
        if (preDS == null) {
            preDS = billDs;
            preDS.copy().print(true);
        } else {//合并两个结果集

            preDS.copy().print(true);
            billDs.copy().print(true);
            //(4)采购入库单数据和生产入库入库单数据合并,相同的仓库和物料合并到同一条数据中
            preDS = myUnionDs(preDS, billDs, index);
        }
    }
        //是否需要删除旧的数据
             this.deleteAllData();
        if (preDS != null) {
            //分批往中间表插入数据
            this.save(preDS);
        }

}

四、效果图

点击手工执行调度计划

image.png

打开入库直接列表,可以看采购入库和生产入库本日和本月数据已插入中间表。

image.png

五、开发环境版本

V5.0.012

六、参考资料


共享任务中心的个人任务排名报表(报表)

开发平台

学习成长中心

SDK接口

开发必备100个小知识

开发案例库


图标赞 0
0人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!