一尘不染

在MySQL中使用HQL,如何在分组依据之前排序结果集,以便选择正确的记录?

hibernate

有没有办法在单个查询中用HQL(或可能使用Hibernate Criteria)编写每组最大n个查询?

我正在努力解决与以下问题类似的问题:

架构:

  • 这本书有一个发布日期
  • 本书有一位作者
  • 作者有出版者

我手边有出版商,还有搜索日期。对于所有该出版商的作者,我想查找他们在搜索日期之前最近出版的书。

我一直在尝试使其工作(并研究了hibernate状态下的许多其他问题以及“每组最多”),但没有找到任何有效的示例。

在直接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状态下,我无法构造一个模拟此条件的子查询。我也没有运气尝试使用这样的hading子句,它返回零结果。如果我删除了hading子句,它会返回数据库中的第一本书(基于其ID),因为group
by发生在order by之前:

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])

有什么方法可以让hibernate状态执行我想做的事情,而不必旋转内存中的对象或跳回原始SQL?

这是针对MySQL数据库的,如果重要的话,可以通过Grails使用Hibernate。


阅读 256

收藏
2020-06-20

共1个答案

一尘不染

为此,您需要一个SQL窗口函数。在Hibernate/ HQL中无法做到这一点,HQL不支持窗口功能。

greatest-n-per-group标签具有正确答案。例如,这种方法可读性很强,尽管并不总是最佳的。

2020-06-20