2

考虑这种情况:我有一张课程表,每节课都有一周中的一天(0-6;不是日期)和上课时间(不是时间,而是一天中课程的序号,即 1 到 10)。我需要在特定的日期和时间之后找到第一节课。

鉴于这些课程(白天时间):星期一 5、星期三 2、星期五 1、星期五 3。

对于周三 2 之后的课程,我会在 friday-1、friday-3 在friday-2 之后、monday-5 在friday-5 之后收到,依此类推。所以它在周末“溢出”。

在我使用 Hibernate HQL 的一个项目中,我通过以下查询解决了这个问题:

SELECT l FROM Lesson l
ORDER BY (l.day > :day OR (l.day = :day AND l.hour >= :hour)),
l.day DESC, l.hour DESC LIMIT 1

令人惊讶的是,这确实有效,尽管我真的不记得我是怎么想出来的。这是一个真正的魔法。

但是现在我需要在另一个使用 JPA 和 Hibernate 的项目(这次是基于 Java EE 的 Web)中进行。认为它会工作相同(再次使用 Hibernate 和 HQL),它会抛出异常:

org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: OR near line 1, column 101

它指向 ORDER BY 子句中的 OR。

我知道 ORDER BY 中的 OR 真的很尴尬,但它确实有效,所以我认为它没问题。但现在我不知道该怎么处理它。可能是因为不同的 Hibernate 版本还是因为使用了 JPA?(我不确定版本,两者都是 Hibernate 3)。两个数据库都是 MySQL。

感谢您的任何帮助(或提供另一个按指定工作的查询)。

4

1 回答 1

0

免责声明,我真的不太了解 Hibernate,所以我将假设l.day > :day在你的order by“返回”中是一个布尔值。

我有点惊讶这完全有效。在这种情况下,我会使用一个case声明,以便非常清楚发生了什么:

SELECT <columns>
  FROM Lesson l
 ORDER BY case when (l.day > :day OR (l.day = :day AND l.hour >= :hour)) then 1
               else 0 end DESC
        , l.day DESC
        , l.hour DESC 
 LIMIT 1
于 2012-04-21T13:09:17.877 回答