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

如何使用QueryDSL从子查询平均值集合中计算总平均值

解决方案

你需要将原有的分组查询作为子查询嵌套在外层查询的from子句中即可实现等效原生SQL的效果,完整实现代码如下:

import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;

public Double calculateTotalAvgQuality() {
    QSearchRequestItem requestItem = QSearchRequestItem.searchRequestItem;

    // 构造内层子查询:对应原生SQL的group by部分
    var innerSubQuery = JPAExpressions
            .select(
                    requestItem.quality.avg().as("avg_quality"),
                    requestItem.user.countDistinct().as("user_count")
            )
            .from(requestItem)
            .groupBy(requestItem.request)
            .having(
                    requestItem.quality.avg().isNotNull(),
                    requestItem.user.countDistinct().gt(2)
            );

    // 构造外层查询:计算子查询结果中avg_quality的总平均值
    NumberExpression<Double> avgQualityField = Expressions.numberTemplate(Double.class, "{0}", innerSubQuery.get("avg_quality"));
    
    // 直接返回最终计算结果,如需返回JPAQuery对象可删除fetchOne()并修改返回值类型
    return queryFactory
            .select(avgQualityField.avg())
            .from(innerSubQuery)
            .fetchOne();
}

注意事项

  • 该实现依赖JPA提供商对FROM子句子查询的支持:Hibernate 5.1及以上版本原生支持该特性,其他JPA实现请提前确认兼容性
  • 原有代码中的leftJoin(requestItem.user, user)可以省略,requestItem.user.countDistinct()会自动生成count(distinct user_id)的SQL语句,无需额外关联用户表
  • 如果你使用的QueryDSL版本低于4.x,可将JPAExpressions替换为new JPASubQuery()构造子查询,逻辑完全一致

内容的提问来源于stack exchange,提问作者jlemon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:57:03