【问题标题】:Using HQL with MySQL how can I order the result set before the group by so the right record is picked?将 HQL 与 MySQL 一起使用,如何在 group by 之前对结果集进行排序,以便选择正确的记录?
【发布时间】:2011-11-25 14:05:35
【问题描述】:

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

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

架构:

  • 图书有一个出版日期
  • 图书有作者
  • 作者有一个出版商

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

我一直在努力解决这个问题(并查看了hibernategreatest-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。

【问题讨论】:

    标签: mysql hibernate grails greatest-n-per-group


    【解决方案1】:

    为此,您需要SQL window function。在 Hibernate/HQL 中没有办法,HQL 不支持窗口函数。

    greatest-n-per-group 标签有正确答案。例如,this approach 可读性很强,但并不总是最优的。

    【讨论】:

    • 谢谢,“窗口函数”是我遗漏的搜索词,我已经通过一些额外的搜索确认 HQL 绝对不支持它们,并且没有一些语法我'米失踪。看起来它是本机 SQL 或在此类问题的代码中旋转结果集。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 2022-08-11
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多