You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JOOQ查询主信息并实现子查询SUM聚合(无需连接分组)

优化JOOQ查询:SELECT中嵌入SUM聚合的简洁写法

我需要用JOOQ查询主表信息,同时在SELECT语句中使用SUM聚合函数,且不想用额外的JOIN和GROUP语句。目前已经实现了可行方案,但代码结构不够简洁优雅,现有代码如下:

dslContext.select(
                T_DAILY_DIAGRAM.DAILY_DIAGRAM_ID.convertFrom(DailyDiagramId::of),
                T_DAILY_DIAGRAM.BALANCING_GROUP_ID.convertFrom(BalancingGroupId::of),
                T_DAILY_DIAGRAM.DIAGRAM_DATE,
                row(
                        T_DAILY_DIAGRAM_REVISION.DAILY_DIAGRAM_REVISION_ID.convertFrom(DailyDiagramRevisionId::of),
                        T_DAILY_DIAGRAM_REVISION.REVISION_NUMBER,
                        T_DAILY_DIAGRAM_REVISION.PROPAGATION_STATUS.convertFrom(DailyDiagramRevisionPropagationStatus::valueOf),
                        multiset(
                               select(
                                       sum(T_DAILY_DIAGRAM_PERIOD.PRODUCTION).as("production")
                               ).from(T_DAILY_DIAGRAM_PERIOD).where(T_DAILY_DIAGRAM_PERIOD.FK_DAILY_DIAGRAM_REVISION_ID.eq(T_DAILY_DIAGRAM_REVISION.ID))
                        ).convertFrom(p -> p == null || p.isEmpty() ? null : (BigDecimal) p.getValue(0, "production")),
                        row(
                                T_DAILY_DIAGRAM_REVISION.CREATED_AT,
                                T_DAILY_DIAGRAM_REVISION.CREATED_BY,
                                T_DAILY_DIAGRAM_REVISION.UPDATED_AT,
                                T_DAILY_DIAGRAM_REVISION.UPDATED_BY
                        ).convertFrom(Records.mapping(MetadataResponse::newWithoutVersion))
                ).convertFrom(Records.mapping(DailyDiagramRevisionListResponse::new)),
                row(
                        T_DAILY_DIAGRAM.CREATED_AT,
                        T_DAILY_DIAGRAM.CREATED_BY,
                        T_DAILY_DIAGRAM.UPDATED_AT,
                        T_DAILY_DIAGRAM.UPDATED_BY,
                        T_DAILY_DIAGRAM.VERSION
                ).convertFrom(Records.mapping(MetadataResponse::newWithoutCA))
        )
                .from(T_DAILY_DIAGRAM)
                .join(T_DAILY_DIAGRAM_REVISION).on(T_DAILY_DIAGRAM_REVISION.FK_DAILY_DIAGRAM_ID.eq(T_DAILY_DIAGRAM.ID).and(T_DAILY_DIAGRAM_REVISION.CLOSING_TIME.isNull()))
                .where(
                        T_DAILY_DIAGRAM.BALANCING_GROUP_ID.eq(balancingGroupId.id().get())
                        .and(T_DAILY_DIAGRAM.DIAGRAM_DATE.between(startDate, endDate)))
                .fetch(Records.mapping(DailyDiagramListResponse::new));

优化方向及代码示例

  1. 用标量子查询替代multiset:原来的multiset返回集合后需要手动提取值,改用selectValue直接返回聚合结果,省去空集合判断逻辑
  2. 提取重复映射逻辑:将元数据对象的创建逻辑提取为变量,减少代码重复
  3. 优化代码缩进与换行:调整嵌套结构的排版,提升代码可读性

优化后的代码:

// 提取重复的元数据映射逻辑,减少冗余书写
var revisionMetadataMapping = Records.mapping(MetadataResponse::newWithoutVersion);
var diagramMetadataMapping = Records.mapping(MetadataResponse::newWithoutCA);

// 用标量子查询直接计算SUM结果
Field<BigDecimal> productionSum = selectValue(sum(T_DAILY_DIAGRAM_PERIOD.PRODUCTION))
        .from(T_DAILY_DIAGRAM_PERIOD)
        .where(T_DAILY_DIAGRAM_PERIOD.FK_DAILY_DIAGRAM_REVISION_ID.eq(T_DAILY_DIAGRAM_REVISION.ID))
        .asField("production");

dslContext.select(
        T_DAILY_DIAGRAM.DAILY_DIAGRAM_ID.convertFrom(DailyDiagramId::of),
        T_DAILY_DIAGRAM.BALANCING_GROUP_ID.convertFrom(BalancingGroupId::of),
        T_DAILY_DIAGRAM.DIAGRAM_DATE,
        row(
                T_DAILY_DIAGRAM_REVISION.DAILY_DIAGRAM_REVISION_ID.convertFrom(DailyDiagramRevisionId::of),
                T_DAILY_DIAGRAM_REVISION.REVISION_NUMBER,
                T_DAILY_DIAGRAM_REVISION.PROPAGATION_STATUS.convertFrom(DailyDiagramRevisionPropagationStatus::valueOf),
                productionSum,
                row(
                        T_DAILY_DIAGRAM_REVISION.CREATED_AT,
                        T_DAILY_DIAGRAM_REVISION.CREATED_BY,
                        T_DAILY_DIAGRAM_REVISION.UPDATED_AT,
                        T_DAILY_DIAGRAM_REVISION.UPDATED_BY
                ).convertFrom(revisionMetadataMapping)
        ).convertFrom(Records.mapping(DailyDiagramRevisionListResponse::new)),
        row(
                T_DAILY_DIAGRAM.CREATED_AT,
                T_DAILY_DIAGRAM.CREATED_BY,
                T_DAILY_DIAGRAM.UPDATED_AT,
                T_DAILY_DIAGRAM.UPDATED_BY,
                T_DAILY_DIAGRAM.VERSION
        ).convertFrom(diagramMetadataMapping)
)
.from(T_DAILY_DIAGRAM)
.join(T_DAILY_DIAGRAM_REVISION)
    .on(T_DAILY_DIAGRAM_REVISION.FK_DAILY_DIAGRAM_ID.eq(T_DAILY_DIAGRAM.ID)
        .and(T_DAILY_DIAGRAM_REVISION.CLOSING_TIME.isNull()))
.where(
        T_DAILY_DIAGRAM.BALANCING_GROUP_ID.eq(balancingGroupId.id().get())
        .and(T_DAILY_DIAGRAM.DIAGRAM_DATE.between(startDate, endDate))
)
.fetch(Records.mapping(DailyDiagramListResponse::new));

内容的提问来源于stack exchange,提问作者Where is waldo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:02:12