HQL / SQL / Criteria для объединения всех записей в данном списке при выборе всех полей - PullRequest
2 голосов
/ 17 ноября 2011

Я пытаюсь написать запрос HQL / Criteria / Native SQL, который будет возвращать всех сотрудников, назначенных списку проектов.Они должны быть назначены всем проектам, чтобы их можно было выбрать.

Приемлемый способ достижения этого с помощью собственного SQL можно найти в ответе на этот вопрос: T-SQL- Как написать запрос, чтобы получить записи, которые соответствуют ВСЕМ записям в соединении «многие ко многим» :

SELECT e.id 
FROM employee e 
    INNER JOIN proj_assignment a 
        ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]

Однако я хочу выбрать все поля Employee (e.*).Невозможно определить группировку SQL по всем столбцам (GROUP BY e.*), вместо этого следует использовать DISTINCT.Есть ли способ использовать DISTINCT вместе с COUNT(*) для достижения того, чего я хочу?

Я также пытался использовать HQL для выполнения этого запроса.Классы Employee и ProjectAssignment не имеют связи, поэтому невозможно использовать критерии для их присоединения.Я использую перекрестное соединение, потому что это способ выполнения соединения без ассоциации в HQL .Итак, мой HQL выглядит как

select emp from Employee emp, ProjectAssignment pa 
where emp.id = pa.empId and pa.paId IN :list 
group by emp having count(*) = :listSize

Однако из-за ошибки в Hibernate сущность GROUP BY не работает .SQL, который он выводит, выглядит примерно так: group by (emptable.id).

Подзапрос таблицы назначений для каждого проекта (динамическое добавление and exists (select 1 from proj_assignment pa where pa.emp_id=e.id and pa.proj_id = [anId]) для каждого проекта в списке) не является приемлемым вариантом.Есть ли способ написать этот запрос правильно, желательно на HQL (в конце концов, я хочу List<Employee>), без изменения отображений и без явного выбора всех столбцов в собственном SQL?


РЕДАКТИРОВАТЬ : я использую Oracle 10g и hibernate-annotations-3.3.1.GA

Ответы [ 2 ]

0 голосов
/ 18 ноября 2011

Я нашел альтернативный способ достижения этого в HQL, он гораздо более неэффективен, чем мне бы хотелось (и чем то, что действительно возможно без этой неприятной ошибки), но по крайней мере он работает. Это лучше, чем повторять подвыборы для каждого проекта, такие как

and exists (select 1 from project_assignment pa where pa.id = someId and pa.emp_id = e.id)

Он состоит из выполнения подзапроса самостоятельного объединения, чтобы выяснить для каждого из сотрудников, сколько проектов в списке им назначено, и ограничить результаты только теми, которые есть во всех них.

select e 
from Employee
where :listSize = 
    (select distinct count(*)
     from Employee e2, ProjectAssignment pa
     where 
         e2.id = pa.id_emp and 
         e.id = e2.id
         and pa.proj_id IN :projectIdList
    )
0 голосов
/ 18 ноября 2011

Как насчет:

select * from employee x where x.id in(
SELECT e.id 
FROM employee e 
    INNER JOIN proj_assignment a 
        ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]
)
...