使用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));
优化方向及代码示例
- 用标量子查询替代multiset:原来的multiset返回集合后需要手动提取值,改用
selectValue直接返回聚合结果,省去空集合判断逻辑 - 提取重复映射逻辑:将元数据对象的创建逻辑提取为变量,减少代码重复
- 优化代码缩进与换行:调整嵌套结构的排版,提升代码可读性
优化后的代码:
// 提取重复的元数据映射逻辑,减少冗余书写 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
相关产品推荐
相关产品推荐

