hln*_*n98 2 java field aggregate sum jooq
你好我有一个方法来计算数据库中的值,我使用jooq然后迭代结果来进行求和,聚合一些字段.我的问题是我可以在jooq语句中执行所有操作,而不必遍历我的resultSet并手动添加它们吗?这是我到目前为止所做的:谢谢.
BigDecimal dealDiscountAmt = BigDecimal.ZERO;
BigDecimal standardAmtOneTimeTrue = BigDecimal.ZERO;
BigDecimal standardAmtOneTimeFalse = BigDecimal.ZERO;
BigDecimal oneTimeFalseX12 = BigDecimal.ZERO;
/** Dao for jooq access to db. */
@Resource(name = "dmDaoContext")
protected DSLContext dmDao_;
List<JDealMetricWorkflowCriteriaRecord> retValList = new ArrayList<JDealMetricWorkflowCriteriaRecord>();
JDealMetricWorkflowCriteriaRecord newDealRecord = new JDealMetricWorkflowCriteriaRecord();
List<JMetricServicePxvRecord> records = dmDao_.selectFrom(METRIC_SERVICE_PXV)
.where(METRIC_SERVICE_PXV.DEAL_ID.eq(dealId), METRIC_SERVICE_PXV.PRODUCED_DATETIME.eq(whenProduced))
.fetch();
for (JMetricServicePxvRecord record : records) {
//sum all dealDiscounts
dealDiscountAmt = dealDiscountAmt.add(record.getStandardTotalPxv().subtract(record.getProposedTotalPxv());
if (record.getOneTime()) {
//sum all dealDiscounts if oneTime is true
standardAmtOneTimeTrue = standardAmtOneTimeTrue.add(record.getStandardTotalPxv().subtract(record.getProposedTotalPxv());
} else {
//sum all dealDiscounts if oneTime is false
standardAmtOneTimeFalse = standardAmtOneTimeFalse.add(record.getStandardTotalPxv().subtract(record.getProposedTotalPxv());
}
}
oneTimeFalseX12 = standardAmtOneTimeFalse.multiply(new BigDecimal("12"));
newDealRecord.setDealDiscount(dealDiscountAmt);
newDealRecord.setAnnualizedDealDiscount(standardAmtOneTimeTrue.add(oneTimeFalseX12));
retValList.add(newDealRecord);
Run Code Online (Sandbox Code Playgroud)
jOOQ可以完成SQL可以执行的所有操作.
以下是在每个数据库上运行的标准SQL:
SELECT
SUM(standard_total_pxv - proposed_total_pxv)
AS deal_discount,
SUM(CASE WHEN one_time = 1 THEN standard_total_pxv - propsed_total_pxv END) +
SUM(CASE WHEN one_time != 1 THEN standard_total_pxv - propsed_total_pxv END) * 12
AS annualized_deal_discount
FROM metric_service_pxv
WHERE deal_id = :dealId AND produced_datetime = :whenProduced
Run Code Online (Sandbox Code Playgroud)
我假设你的ONE_TIME专栏是一个NUMBER(1).如果您正在使用某种BOOLEAN类型(如果您的数据库支持该类型),那么您可以直接将该列用作谓词:
... WHEN one_time THEN ...
Run Code Online (Sandbox Code Playgroud)
这个SUM(CASE ...)成语利用了SQL SUM()只聚合非NULL值的事实.因此,所有不需要的行都通过制作而从总和中移除NULL,具体取决于值ONE_TIME
// Assuming this static import
import static org.jooq.impl.DSL.*;
Run Code Online (Sandbox Code Playgroud)
然后:
// Aliasing the table for brevity
MetricServicePxv m = METRIC_SERVICE_PXV.as("m");
// Reusing this sum several times:
AggregateFunction<BigDecimal> sum = sum(m.STANDARD_TOTAL_PXV.sub(m.PROPOSED_TOTAL_PXV));
// Here's your result:
Record2<BigDecimal, BigDecimal> result =
dmDao_
.select(
sum.as("DEAL_DISCOUNT"),
sum.filterWhere(m.ONE_TIME.eq(1)).add(
sum.filterWhere(m.ONE_TIME.ne(1)).mul(12)).as("ANNUALIZED_DEAL_DISCOUNT"))
.from(m)
.where(m.DEAL_ID.eq(dealId).and(m.PRODUCED_DATETIME.eq(whenProduced)))
.fetchOne();
Run Code Online (Sandbox Code Playgroud)
FILTER (WHERE ...)AggregateFunction.filterWhere()为简单起见,我在这里使用这个功能.SUM(...) FILTER (WHERE ...)是一种SQL标准语言功能,目前仅在PostgreSQL和HSQLDB中实现.在所有其他数据库中,SUM(CASE ...)生成聚合函数.