HQL для получения элементов, которые обладают всеми элементами в наборе - PullRequest
1 голос
/ 21 мая 2010

В настоящее время у меня есть HQL-запрос, который возвращает всех Участников, обладающих ЛЮБОЙ Премией из набора указанных Наград:

from Member m left join m.awards as a where a.name in ("Trophy","Ribbon");

Что мне сейчас нужно, так это HQL, который вернет всех Участников, которые обладают ALL Наградами, указанными в наборе Наград.

Итак, предполагая эти данные:

Joe has Trophy, Medal
Sue has Trophy, Ribbon
Tom has Trophy, Ribbon, Medal

Приведенный выше запрос вернет Джо, Сью и Тома, потому что у всех троих есть хотя бы один трофей или лента. Но мне нужно вернуть только Сью и Тома, потому что они единственные, кто обладает всеми указанными наградами (Трофей и Лента).

Вот структура класса (упрощенная):

class Member {
  private String name;
  private Set<Award> awards;
}
class Award {
  private String name;
}

Ответы [ 3 ]

3 голосов
/ 21 мая 2010
select m from Member m left join m.awards as a where a.name in ("Trophy","Ribbon") group by m having count(a)=2
2 голосов
/ 10 октября 2013

Просто повторяюсь ... Код для получения участников, которые ИМЕННО имеют данный набор наград:

from Member m 
where not exists (
  from Award a where a.name in {"Trophy", "Ribbon"} 
  and a not in( 
    select * from Award a2 where a2.owner = m 
  ) 
) and not exists ( 
  from Award a3 where a3.owner = m and a3 not in {"Trophy", "Ribbon"} 
) 
0 голосов
/ 05 февраля 2013

Вы можете форсировать отдельные результаты, добавив преобразователь результатов DISTINCT_ROOT_ENTITY к вызову запроса, IE:

getSession().createQuery(hql).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

У меня похожая проблема, но мне нужно (следуя вашему примеру) выбрать всех участников, которым принадлежат ВСЕ награды, и не более. Так что в вашем примере единственным правильным результатом будет Сью. Есть идеи?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...