在 JPA @NamedQuery 中的 FROM 子句中使用 sub-select

Using sub-select in FROM clause inside JPA @NamedQuery

在我的应用中,我需要使用@NamedQuery 来查找分配给特定帐户的最频繁操作的类型[​​=14=]

@Entity
@Table(name="\"ACCOUNTOPERATION\"")
@NamedQuery(name="AccountOperation.findTypeOfMostFrequentOperation", query="" +
        "SELECT ao.type from AccountOperation ao WHERE ao.account.id = ?1 " +
        "GROUP BY ao.type HAVING COUNT(ao) = (" +
            "SELECT MAX(typeCountQuery.typeCount) " +
            "FROM (" +
                "SELECT COUNT(aop) as typeCount " +
                "FROM AccountOperation aop WHERE aop.account.id = ?1 GROUP BY aop.type" +
            ") as typeCountQuery" +
        ")"
)
public class AccountOperation {

    @ManyToOne
    private Account account;
    private BigDecimal amount;
    private OperationType type;
...

紧接在 FROM 子句之后的“(”字符,开始 typeCountQuery 的正文我得到

')', ',', GROUP, HAVING, IN, WHERE or identifier expected, got '('

我读过 JPA does not support sub-selects in the FROM clause,那么有什么方法可以重写 SQL 代码以在 @NamedQuery 中继续使用它吗?

我将 IntelliJ IDE 与 H2 DB 以及 eclipselink 和 javax.persistence 依赖项一起使用。

type最高countreturns以下查询

select type
from AccountOperation
where id = ?
group by type
order by count(*) desc
fetch first 1 ROWS only

你应该知道 ties 的存在,即更多 types 具有相同的 maximal 计数和应该考虑一下如何处理它们。

即在 Oracle 中,你可以说 fetch first 1 ROWS WITH TIES 来获得所有 typemaximal 计数。

Link to source

在 JPQL 中,您不能使用子查询。要解决此问题,您需要使用一些关键字,如 ALL、ANY,它们的效果类似。

所以在你的情况下它可能是:

@NamedQuery(name="AccountOperation.findTypeOfMostFrequentOperation", query="" +
    "SELECT ao.type from AccountOperation ao WHERE ao.account.id = ?1 " +
    "GROUP BY ao.type HAVING COUNT(ao) >= ALL (" +
            "SELECT COUNT(aop) as typeCount " +
            "FROM AccountOperation aop WHERE aop.account.id = ?1 GROUP BY aop.type)"