QueryDSL GroupBy和求和

时间:2018-11-23 09:50:11

标签: postgresql querydsl

我有以下QueryDSL语句:

BooleanExpression alwaysTrueExpression = match(null, null, datePeriod, period);

if (minAmount != null) {
    alwaysTrueExpression = alwaysTrueExpression.and(aggregatedOrder.totalUnitAmountWithoutTax.sum().goe(minAmount));
}
if (maxAmount != null) {
    alwaysTrueExpression = alwaysTrueExpression.and(aggregatedOrder.totalUnitAmountWithoutTax.sum().loe(maxAmount));
}

JPAQuery<AggregatedOrder> query = selectFrom(aggregatedOrder);
query = query.where(alwaysTrueExpression);
log.debug("sql={}", query);

return query.transform(GroupBy.groupBy(aggregatedOrder.tradingPromoterBranch.promoter).as(GroupBy.sum(aggregatedOrder.totalUnitAmountWithoutTax)));

但是会引发错误:

Caused by: org.postgresql.util.PSQLException: ERROR: aggregate functions are not allowed in WHERE

我想按启动子对aggregatedOrder进行分组,并用金额进行过滤。

2 个答案:

答案 0 :(得分:1)

我认为您正在混合使用Querydsl支持的两种分组方式:

  • query.transform(...):一旦从数据库中获取数据,就将结果分组到内存中。在这种情况下,查询不会包含“ group by”子句,并且数据转换是在“ java端”执行的。
  • query.groupBy(...):将group by子句添加到您的查询中。在这种情况下,分组由数据库执行。

如果查询中需要聚合函数,则需要使用“ query.groupBy(...)”提供“分组依据”列。

答案 1 :(得分:1)

这是我汇总列并按总和过滤的方法:

BooleanExpression alwaysTrueExpression = Expressions.asBoolean(true).isTrue();

NumberExpression<BigDecimal> totalUnitAmountWithoutTax = aggregatedOrder.totalUnitAmountWithoutTax.sum();
NumberExpression<Integer> totalQuantity = aggregatedOrder.quantity.sum();
NumberPath<Long> qPromoter = aggregatedOrder.tradingPromoterBranch.promoter.id;

BooleanExpression amountExpression = Expressions.asBoolean(true).isTrue();
if (minAmount != null) {
    amountExpression = amountExpression.and(totalUnitAmountWithoutTax.goe(minAmount));
}
if (maxAmount != null) {
    amountExpression = amountExpression.and(totalUnitAmountWithoutTax.loe(maxAmount));
}

JPAQuery<Tuple> query = jpaQueryFactory.select(qPromoter, totalUnitAmountWithoutTax, totalQuantity).from(aggregatedOrder).groupBy(qPromoter);
query = query.where(alwaysTrueExpression).having(amountExpression);

return query.fetch();