将 HQL 与 MySQL 一起使用,如何在 group by 之前对结果集进行排序,以便选择正确的记录?
Posted
技术标签:
【中文标题】将 HQL 与 MySQL 一起使用,如何在 group by 之前对结果集进行排序,以便选择正确的记录?【英文标题】:Using HQL with MySQL how can I order the result set before the group by so the right record is picked? 【发布时间】:2011-11-25 14:05:35 【问题描述】:有没有办法在单个查询中用 HQL(或可能使用 Hibernate Criteria)编写每个组的最大 n 个查询?
我正在努力解决与此类似的问题:
架构:
图书有一个出版日期 图书有作者 作者有一个出版商我手头有一个出版商,还有一个搜索日期。对于所有该出版商的作者,我想找到他们在搜索日期之前最近出版的书。
我一直在努力解决这个问题(并查看了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
这会强制 order by 在子查询中首先发生,然后 group by 发生在之后,并选择最近出版的书作为第一个分组依据。我将作者 ID 与图书 ID 和出版日期配对。 (我知道这在 SQL 中不是一种特别有效的方法,这只是在本机 SQL 中易于理解的一种方法的示例)。
在休眠状态下,我无法构造一个模拟这个的子查询。我也没有任何运气尝试使用这样的有子句,它返回零结果。如果我删除了having子句,它会返回数据库中的第一本书(基于它的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。
【问题讨论】:
【参考方案1】:为此,您需要SQL window function。在 Hibernate/HQL 中没有办法,HQL 不支持窗口函数。
greatest-n-per-group
标签有正确答案。例如,this approach 可读性很强,但并不总是最优的。
【讨论】:
谢谢,“窗口函数”是我遗漏的搜索词,我已经通过一些额外的搜索确认 HQL 绝对不支持它们,并且没有一些语法我'米失踪。看起来它是本机 SQL 或在此类问题的代码中旋转结果集。以上是关于将 HQL 与 MySQL 一起使用,如何在 group by 之前对结果集进行排序,以便选择正确的记录?的主要内容,如果未能解决你的问题,请参考以下文章