HQL: проблема с тривиальным выбором с агрегатной функцией - PullRequest
1 голос
/ 30 августа 2011

У меня очень простая модель данных, подобная этой:

create table Company (
    id int primary key,
    name varchar(50),
    street varchar(50)
)

create table Person (
    id int primary key,
    name varchar(50),
    surname varchar(50),
    id_company int foreign key references Company
)

соответствующие классы Java, как это:

class Company {
    int id;
    String name, street;
    List<Person> employees;
    // getters, setters, ctor
}

class Person {
    int id;
    String name, surname;
    Company employer;
    // getters, setters, ctor
}

Теперь я бы хотел выбрать Компанию с большинством сотрудников с HQL . Я не знаю, как, вот моя псевдо-попытка мусора, которая не работает:

from Company c having max(c.employees);

Ответы [ 4 ]

3 голосов
/ 30 августа 2011

РЕДАКТИРОВАТЬ: это сработало для меня - чтобы получить идентификатор компании и количество сотрудников

select c.id, max(c.employees.size) from Company c

Чтобы получить объект компании:

from Company comp
where comp.employees.size = (
  select max(c.employees.size) from Company c
)

Если у вас нет плагина гибернациидля eclipse, но установите его, он отлично подходит для этого, поскольку он также отображает сгенерированный sql, чтобы вы могли оптимизировать hql, см. http://www.hibernate.org/subprojects/tools.html.

Просто подумал о чем-то, что произойдет, если две компании CompA и CompB обау вас самое большое количество сотрудников, скажем, 50, т. е. во всех других компаниях менее 50 человек. Вас волнует, какую компанию вы вернете?Вас больше интересует номер 50 или идентификатор компании?

2 голосов
/ 30 августа 2011

Это не тривиально, на самом деле.Я не могу придумать способ сделать то, что вы хотите, с помощью одного запроса, но вы можете сделать это с двумя запросами, используя что-то вроде этого:

String hql = "select p.employer.id, count(*) from Person p group by p.employer.id order by count(*) desc";
Query query = session.createQuery(hql);
query.setMaxResults(1);
List<Object[]> list = (List<Object[]>) query.list();
Object[] oa = list.get(0);
Integer companyId = oa[0];
Company company = session.get(Company.class, companyId);

Приведенный выше код предполагает, что есть только одна компанияэто имеет большинство сотрудников.Разумеется, у нескольких компаний может быть одинаковое количество сотрудников, которое также является максимальным.

0 голосов
/ 31 августа 2011

Попробуйте:

select company from Company company order by company.employees.size

В коде вы получаете только первый элемент.

query.setMaxResult(1);
0 голосов
/ 30 августа 2011

Ознакомьтесь с главой Hibernate по HQL , в частности с разделом агрегатной функции:

select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from Cat cat

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