2011-09-26 45 views
1

有沒有什麼方法可以在單個查詢中編寫HQL(或潛在的Hibernate標準)中最大的每組查詢?在MySQL中使用HQL如何在組之前排序結果集,以便選擇正確的記錄?

我與這類似這樣一個問題所困擾:

模式:

  • 書有中的publication_date
  • 書有
  • 作者有一個出版社的作者

我有一個出版商在手中,以及搜索日期。對於該出版商的所有作者,我想在搜索日期之前找到他們最近發佈的圖書。

我一直試圖讓這個工作(並已看過hibernate以及greatest-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 

這迫使爲了通過由事後發生在子查詢第一發生,則該組,並挑選最近出版的書作爲第一項分組。我將作者ID與書籍ID和出版日期配對。 (我知道在SQL中這不是一種特別有效的方法,這只是在本機SQL中使用易於理解的一種方法的一個例子)。

在hibernate中,我一直無法構建一個模仿這個的子查詢。我也沒有嘗試使用這樣的子句有任何運氣,它返回零結果。如果我刪除having子句,它通過訂單之前發生返回數據庫中的第一本書(基於它的ID)作爲組:

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數據庫,並通過Grails使用Hibernate(如果它很重要)。

回答

4

對此,您需要一個SQL window function。在Hibernate/HQL中沒有辦法做到,HQL不支持窗口功能。

greatest-n-per-group標記有正確的答案。例如,this approach非常易讀,但並不總是最佳。

+0

謝謝,「窗口函數」是我錯過的搜索術語,我通過一些額外的搜索證實HQL絕對不支持它們,並且沒有一些我錯過的語法。看起來像是原生SQL或者通過代碼中的結果集旋轉這類問題。 –

相關問題