2016-12-21 1 views
1

Я пытаюсь получить запрос , и я хотел бы LEFT JOIN таблицу с самим собой, чтобы получить запрос форма:JOIN таблица с самим собой с использованием API JPA Criteria (или иначе решайте наибольшую-n-на-группу)

SELECT a.* 
FROM YourTable a 
LEFT OUTER JOIN YourTable b 
    ON a.id = b.id AND a.rev < b.rev 
WHERE b.id IS NULL; 

(взято из https://stackoverflow.com/a/7745635/1982385)

Я хотел бы осуществить это, используя критерии запроса JPA (с использованием Hibernate 5.2.4.Final), но единственный способ, которым я могу думать об этом:

// query is a CriteriaQuery<> 
Root<YourTable> queryRootTable = query.from(YourTable.class); 
Join<YourTable, YourTable> selfJoin = queryRootTable.join(queryRootTable); 

Я сделал несколько запросов, добавив условия для .join() с помощью .on(), но я не знаю, как я бы выполнить .join() без отображения. В качестве альтернативы можно было бы оценить еще один способ поиска наибольшей-n-группы. (Я пытаюсь найти ряд с наибольшим rev, для каждого id, поэтому прямой SELECT MAX(rev)... не работает).

+1

Вы пытались присоединиться два экземпляра 'YourTable' ... без использования присоединиться, но просто с' where' состоянии? – perissf

+0

ie "SELECT a FROM YourEntity a, YourEntity b WHERE ..." –

+0

Я пробовал кросс-соединение, как вы сказали, положив условие в WHERE, но оно не работает (похоже, это зависит от того, как LEFT JOIN работает, чтобы решить проблему). –

ответ

0

Прошу прощения, если я полностью не понял ваш вопрос и что вы подразумеваете под «без сопоставления», моя репутация позволяет мне еще прокомментировать, но я предполагаю, что решение заключается в том, чтобы делать неявное соединение, используя where пункт. (В это экземпляр CriteriaQuery, центибар является экземпляром CriteriaBuilder)

c.where(cb.equal(entity.get("id"), entity2.get("id"); 

Или давайте мы предполагаем, что:

  • YourTable1 отображается entity1.
  • YourTable2 сопоставляется с Entity2.
  • relationshipA является связь между YourTable1 и YourTable2

Два комментария:

Первый шаг, вы должны определить корень YourTable1

Root<Entity1> root = c.from(Entity1.class); 

Второй шаг, вы можете создать присоединиться через отношения YourTable1 и YourTable2 и укажите тип соединения.

Join<Entity1,Entity2> join = root.join("relationshipA", JoinType.LEFT);

+0

Проблема заключается в том, что существует только * one * entity ('YourTable'), поэтому у меня нет отношения« mapping »для меня, чтобы я делал' .join() 'on. В любом случае, спасибо за ответ! (и теперь вы должны иметь возможность комментировать) –

+0

Я вижу, что вы можете самостоятельно ссылаться (относиться к itsellf) и делать 'join', или вы можете присоединиться к' while', даже если у вас есть только одна сущность, сравнивая это атрибуты. Да, я могу прокомментировать сейчас, спасибо. – fg78nc

+0

Я закончил использование собственного SQL-запроса из Hibernate.К сожалению, прямое перекрестное соединение с «где» для сравнения полей не сработало, так как требуемый мне запрос зависит от поведения LEFT JOIN. –