将 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 之前对结果集进行排序,以便选择正确的记录?的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 中,如何将 BETWEEN 与 'AS' 列一起使用

如何将MySql子查询转换为HQL子查询

如何将lampp与外部mysql一起使用

如何将 MySQL 5.x 与 PHP 4.x 一起使用?

如何将 nodeJS 集群与 mySQL 池集群一起使用?

一个承诺的 mysql 模块将如何与 NodeJS 一起工作?