Используя HQL с MySQL, как я могу упорядочить результирующий набор до того, как группа выберет правильную запись? - PullRequest
1 голос
/ 27 сентября 2011

Есть ли какой-нибудь способ написать запрос на наибольшие n на группу в HQL (или, возможно, с Hibernate Criteria) в одном запросе?

Я борюсь с проблемой, которая похожа на эту:

Схема:

  • Книга имеет дату публикации
  • Книга имеет автора
  • Автор имеет издателя

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

Я пытался заставить это работать (и рассмотрел многие другие вопросы в разделе hibernate , а также great-n-per-group ), но я не нашел ни одного работающего примера.

В прямом MySQL я могу использоватьустановите флажок, чтобы получить следующее:

select * from
(select
        a.id author_id,
        b.id book_id,
        b.publication_date publication_date
   from book b
   join author a on a.id = b.author_id
   join publisher p on p.id = a.publisher_id
  where
    b.publication_date <= '2011-07-01'
    and p.id = 2
order by b.publication_date desc) as t
 group by
    t.author_id

Это заставляет сначала выполнить порядок в подзапросе, а затем - группировать и выбрать самую последнюю опубликованную книгу в качестве первого элемента для группировки.Я получаю идентификатор автора в паре с идентификатором книги и датой публикации.(Я знаю, что это не особенно эффективный способ сделать это в SQL, это просто пример одного из способов сделать это в нативном SQL, который легко понять).

В спящем режиме я былневозможно построить подзапрос, который имитирует это.Мне также не повезло, когда я пытался использовать такое положение, как оно, оно возвращает ноль результатов.Если я удаляю предложение Имеет, он возвращает первую книгу в базе данных (на основе ее идентификатора), так как группировка происходит до заказа по:

Book.executeQuery("""
        select b.author, b
        from Book b 
        where b.publicationDate <= :date
        and b.author.publisher = :publisher
        group by b.author
        having max(b.publicationDate) = b.publicationDate
        order by py.division.id
""", [date: date, publisher: publisher])

Есть ли какой-либо способ получить спящий режим, чтобы сделать то, чтоЯ хочу без необходимости прокручивать объекты в памяти или возвращаться обратно к сырому SQL?

Это против базы данных MySQL и использования Hibernate через Grails, если это имеет значение.

1 Ответ

4 голосов
/ 28 сентября 2011

Для этого вам нужна оконная функция SQL . В Hibernate / HQL нет способа сделать это, HQL не поддерживает оконные функции.

Тег

greatest-n-per-group имеет правильные ответы. Например, этот подход довольно читабелен, хотя и не всегда оптимален.

...