Algo 自定义Group函数实现MySQL的group_concat(distinct)原创
金蝶云社区-时空蔷薇
时空蔷薇
6人赞赏了该文章 2,767次浏览 未经作者许可,禁止转载编辑于2021年12月16日 16:39:24
summary-icon摘要由AI智能服务提供

本文介绍了在Algo系统中,由于当前版本的groupConcat API不支持distinct功能,所以需要通过自定义groupby函数(继承CustomAggFunction)来实现group_concat(distinct)的效果。具体步骤包括继承报表模板并添加字段,实现自定义的GroupConcatWithDistinctFunction类来处理值的添加和去重,并在groupby后调用此函数进行物料名称的去重连接。最后,通过调用查询方法并注册报表取数插件来完成整个实现过程。

标签:

    Algo、自定义groupgroup_concat(distinct)groupconcatCustomAggFunction

需求背景:

    MySQLgroup_concat([distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator '分隔符'] ) 可实现将group by产生的同一个分组中的值连接起来,返回一个字符串结果。通过使用distinct可以排除重复值,比如源单数据如图1,经过select suppliername, group_concat( distinct materialname) from kded_purchaseapply group by suppliername;可实现根据供应商分组后将物料名称进行去重连接(如图2)。

 

 image.png

源单数据

 image.png

group_concat(distinct)数据

    但是Algo当前版本groupConcat API还不支持使用distinct,未来版本可能支持。目前可在调用GroupbyDataSetgroupConcat API后自己使用DataSet.map()或者GroupbyDataSet.reduceGroup()进一步处理,或者继承CustomAggFunction实现自定义groupby函数。

    本案例演示自定义group函数实现group_concat(distinct 要连接的字段),如有其他类似需求仅供参考。

实现方案:

    数据来源:二开单据采购申请单(kded_purchaseapply

                    单据头字段 供应商(kded_org

                    分录(entryentity)字段 物料(kded_materiel

实现步骤如下:

1. 继承报表模板新建一个报表,添加字段[供应商]kded_suppliername)、[物料]kded_materialname)

 

image.png

 

2. 继承CustomAggFunction实现自定义group函数GroupConcatWithDistinctFunction,从而实现group_concat(distinct)的功能。主要重写逻辑如下:

    (1) 重写addValue()方法处理单次添加字段时的值连接逻辑。

实现代码:

/**
 * 原值为空直接返回 拼接新值,否则返回 拼接连接符再拼接新值
 */
@Override
public StringBuilder addValue(StringBuilder aggValue, Object value) {
    if(StringUtils.isBlank(aggValue.toString())) {
        return aggValue.append(value);
    } else {
        return aggValue.append(",").append(value);
    }
}

    (2) 重写getResult()方法在返回合并值时进行去重

实现代码:

/**
 * 返回结果时去重
 */
@Override
public Object getResult(StringBuilder aggValue) {
    String oriValue = aggValue.toString();
    String[] split = oriValue.split(",");
    List<String> distinctList = Arrays.asList(split).stream().distinct().collect(Collectors.toList());
    return String.join(",", distinctList);
}

 

3. 调用groupby根据供应商名称进行分组后,调用自定义的group函数进行物料名称的去重连接。

实现代码:

@Override
public DataSet query(ReportQueryParam queryParam, Object object) throws Throwable {
    QFilter filter = new QFilter("billno", QCP.equals, "APPLY-20211125-0001");
    //获取原始数据集DataSet
    DataSet originalDs = QueryServiceHelper.queryDataSet(this.getClass().getName(), "kded_purchaseapply", "kded_supplier.name as kded_suppliername, entryentity.kded_materiel.name as kded_materialname", filter.toArray(), null);
    //根据供应商名称分组后调用自定义group函数连接字段值
    DataSet ds = originalDs.groupBy(new String[] {"kded_suppliername"}).agg(new GroupConcatWithDistinctFunction("kded_materialname", DataType.StringType), "kded_materialname", "kded_materialname").finish();
    return ds;
}

 

4. 注册报表取数插件。

 image.png

 

实现效果:

1. 原始数据。

 image.png

2.groupConcat(distinct)报表取数。

image.png

    

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