2016-07-28 3 views
1

Мне нужно получить наибольшее и наименьшее значение между двумя полями. Я использую JPA 2.1 с EclipsLink.JPA - синтаксический анализ синтаксиса SELECT GREATEST (c.field, mc.field), LEAST (c.field, mc.field) FROM table

Вот мой запрос упрощена:

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; 

Это делает работу штрафа на MySQL Workbench, в качестве исходного запроса SQL, но когда я скопировать этот запрос к моему 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, (значение) не имеет никакого смысла.

Что я здесь делаю неправильно?

+0

Мое предложение было бы посмотреть на это [SO вопрос] (http://stackoverflow.com/questions/35759093/jpa- functionsquery-с-наименьшими и наибольшими функциями) по той же теме, которая подробно описывает использование CriteriaBuilder для достижения того, что вы ищете. –

+0

@JustinKyleParton спасибо. Это будет мое худшее решение для сценариев. Я пытаюсь избежать, чтобы переписать этот запрос в CriteriaBuilder на данный момент. – dazito

+0

i havent использовал это, поэтому я не стану его ответом, но перейдите на эту страницу [Специальные операторы EclipseLink] (https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#EclipseLink_special_operators) и попробуйте использовать это, чтобы достичь того, чего вы хотите. Также посмотрите на операторы чуть ниже этого. –

ответ

0

Я кончался следующим раствором, смесь MIN/MAX с CASE 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 ... 
1

Совокупные функции greatest и least не поддерживаются JPA 2.0. Они не упоминаются в syntax. Вы пробовали min и max вместо: max(c.min,mc.min), min(c.max,mc.max)?

1

Другой вариант мог бы дополнить диалект базы данных JPA для MySQL. Я не знаком с 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)); 
    } 
} 
+0

Я не пробовал это, так как решил свою проблему, и у меня нет времени на рефакторинг/попробовать этот подход, но это похоже на интересное решение. +1 – dazito