【问题标题】:CriteriaBuilder JPA: Multiselect in Subquery / groupby / maxresultCriteriaBuilder JPA:子查询/groupby/maxresult中的多选
【发布时间】:2019-07-17 22:00:31
【问题描述】:

目前我正在为客户列表开发“过滤器”功能。

我有以下子查询,但我不确定是否有办法使用 CriteriaBuilder 构建它。它也可以在没有多选 b.date, ... 的情况下工作,但我需要 Group ByOrder ByLimit 才能选择最小值。结果应该是一个数字。

SELECT (COALESCE(SUM(b.account1),0) + COALESCE(SUM(b.account2),0) + COALESCE(SUM(b.deposits),0)) AS SUM FROM customer_balance b WHERE b.client_nr = '123455'
GROUP BY b.date
ORDER BY SUM
LIMIT 1

例如客户余额表

"client_nr","date","account1","account2","deposits"
"1234567","2018-02-28",204600.0,82500.0,21120.0

更新: 这是我目前的代码,但是

Subquery<BigDecimal> CustomerBalanceSubQuery = CustomerQuery.subquery(BigDecimal.class);
Root<CustomerBalance> CustomerBalance = CustomerBalanceSubQuery.from(CustomerBalance.class);

Expression<BigDecimal> currentAccount = criteriaBuilder.sum(CustomerBalance.get("currentAccount"));
Expression<BigDecimal> overnightDeposits = criteriaBuilder.sum(CustomerBalance.get("overnightDeposits"));
Expression<BigDecimal> termDeposits = criteriaBuilder.sum(CustomerBalance.get("termDeposits"));

CustomerBalanceSubQuery.select(criteriaBuilder.sum(termDeposits, criteriaBuilder.sum(overnightDeposits, currentAccount)));
Predicate predicate = criteriaBuilder.equal(CustomerBalance.get("id").get("ClientNr"), Customer.get("ClientNr"));
CustomerBalanceSubQuery.where(predicate);

// adding to main-query
queryPredicateList.add(criteriaBuilder.and(criteriaBuilder.greaterThan(CustomerBalanceSubQuery, BigDecimal.valueOf(liquidity))));
  • 如何为我的子查询添加orderBy
  • 如何设置maxResult

谢谢! 乙

【问题讨论】:

  • 既然已经有一个有效的查询,为什么还要使用 Criteria API?
  • 所有 JPQL 查询都应该可以使用 Criteria 构建。首先,您应该发布您尝试过的内容,以及您遇到问题的部分。显然上面不是 JPQL,所以发布 JPQL
  • @SimonMartinelli 我的查询是动态的。根据查询参数,我必须查询不同的表,这实际上是我的挑战。我需要一个子查询来获取不同表中按日期分组的三个总和的最小值。
  • @BillyFrost 你是对的,我更新了问题。
  • 为什么你认为你需要一个子查询?我会尝试使用 Expression&lt;BigDecimal&gt; mySum = criteriaBuilder.&lt;BigDecimal&gt;sum(...) 保存总和结果的简单查询。然后我会对这个表达式 cq.orderBy(criteriaBuilder.desc(mySum)) 应用排序,最后在结果查询上应用 setMaxResults() 方法

标签: jpa persistence criteria-api


【解决方案1】:

在与一些同事交谈后,我将查询重构为:

SELECT min(COALESCE(b.current_account,0) + COALESCE(b.overnight_deposits,0) + COALESCE(b.term_deposits,0)) FROM customer_balance b WHERE b.client_nr = '123456'

还有代码……

Subquery<BigDecimal> customerBalanceSubQuery = customerQuery.subquery(BigDecimal.class);
Root<CustomerBalance> customerBalance = customerBalanceSubQuery.from(CustomerBalance.class);

Expression<BigDecimal> currentAccount = customerBalance.get("currentAccount");
Expression<BigDecimal> overnightDeposits = customerBalance.get("overnightDeposits");
Expression<BigDecimal> termDeposits = customerBalance.get("termDeposits");

customerBalanceSubQuery.select(criteriaBuilder.min(criteriaBuilder.sum(termDeposits, criteriaBuilder.sum(overnightDeposits, currentAccount))));
Predicate predicate = criteriaBuilder.equal(customerBalance.get("id").get("clientNr"), customer.get("clientNr"));
customerBalanceSubQuery.where(predicate);

queryPredicateList.add(criteriaBuilder.and(criteriaBuilder.greaterThan(CustomerBalanceSubQuery, BigDecimal.valueOf(liquidity))));

无论如何,从原始问题中查看查询会很有趣。 除了提到的@BillyFrost,我不确定是否每个 sql 查询都可以使用 Criteria API 构建。

【讨论】:

    猜你喜欢
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2011-06-05
    • 2015-01-30
    • 2020-06-22
    相关资源
    最近更新 更多