JPA - 语法错误解析 SELECT GREATEST(c.field, mc.field), LEAST(c.field, mc.field) FROM table

JPA - Syntax error parsing SELECT GREATEST(c.field, mc.field), LEAST(c.field, mc.field) FROM table

我需要获得两个字段之间的最大和最小值。我将 JPA 2.1 与 EclipsLink 结合使用。

这是我的简化查询:

SELECT GREATEST(c.min, mc.max), LEAST(c.max, mc.max) 
FROM
   MethodCategory mc, OperationMethod om, Client c 
       JOIN
   User u ON c.id = u.client.id
WHERE
   om.method = 1
   AND om.method.category = "SUPER"
   AND om.isDeleted = false 
   AND om.user = u
   AND u.id <> 1 
   AND c.isOnline = TRUE 
   AND c.isActive = TRUE;

作为原始 sql 查询,它在 MySQL Workbench 上运行良好,但是当我将此查询复制到我的 entityManager.createQuery(query) 时,出现异常。

以下是我将查询复制到 JPA 的方法:

TypedQuery<Object[]> query = em.createQuery("SELECT GREATEST(c.min, mc.min), LEAST(c.max, mc.max) "
                + " FROM\n"
                + "    MethodCategory mc, OperationMethod om, Client c \n"
                + "        JOIN\n"
                + "    User u ON c.id = u.client.id \n"
                + " WHERE\n"
                + "    om.method = :method \n"
                + "    AND om.method.category = :categoryName \n"
                + "    AND om.isDeleted = false \n"
                + "    AND om.user = u \n"
                + "    AND u.id <> :userId \n" 
                + "    AND c.isOnline = TRUE \n"
                + "    AND c.isActive = TRUE \n",
                Object[].class);

每当我执行这个 JPQL 查询时,我都会得到这个异常:

Exception Description: Syntax error parsing [SELECT GREATEST(c.min, mc.min), LEAST(c.max, mc.max)  FROM (...)
[14, 15] The SELECT clause has 'GREATEST' and '(c.min, mc.min)' that are not separated by a comma.
[72, 73] The SELECT clause has 'LEAST' and '(c.max, mc.max)' that are not separated by a comma.

这个例外对我来说真的毫无意义。我清楚地用逗号分隔 GREATEST() 和 LEAST() 并且 GREATEST , (value) 没有任何意义。

我在这里做错了什么?

JPA 2.0 不支持聚合函数 greatestleastsyntax 中未提及它们。您是否尝试过 minmaxmax(c.min,mc.min), min(c.max,mc.max)?

我最终得到了以下解决方案,混合了 MIN/MAXCASE THEN

查询如下:

SELECT  
MIN(CASE WHEN (c.min < mc.min) THEN mc.min ELSE c.min END) as min, 
MAX(CASE WHEN (c.max < mc.max) THEN c.max ELSE mc.max END) as max  
FROM ...

另一种选择是为 MySQL 扩充 JPA 数据库方言。我不熟悉 EclipseLink,但对于 Hibernate,它会是这样的:

import org.hibernate.dialect.MySQL5InnoDBDialect;
import org.hibernate.dialect.function.StandardSQLFunction;

public class CustomMySQL5InnoDBDialect extends MySQL5InnoDBDialect {
    public CustomMySQL5InnoDBDialect() {
        super();

        registerFunction("greatest", new StandardSQLFunction("greatest", null));
        registerFunction("least", new StandardSQLFunction("least", null));
    }
}