【问题标题】:Group by result of custom function HIBERNATE按自定义函数 HIBERNATE 的结果分组
【发布时间】:2020-03-09 07:47:07
【问题描述】:

嗨,由于 Hibernate 中的自定义函数,我对 group by 有一些问题。 查询如下:

 @Query("SELECT NEW ReportDay(" +
            "FUNCTION('atTimezone', p.startDate, :timezone), "
            "SUM(p.energy)) " +
            "FROM Process p GROUP BY FUNCTION('atTimezone', p.startDate, :timezone)") 

抛出的错误是 p.startDate 必须出现在 groupBy 子句或聚合函数中。但是自定义函数在group by子句中。

有什么想法吗?自定义函数是这样的:

    registerFunction("atTimezone", new SQLFunctionTemplate(StandardBasicTypes.TIMESTAMP,"date_trunc('day', (cast(?1 as timestamp) AT TIME ZONE cast(?2 as varchar)))"));

并试图在特定时区将日期截断为一天。 非常感谢!

【问题讨论】:

  • 你使用什么hibernate版本,数据库?
  • hibernate-core 5.0.12.Final DB 是 postgre
  • 部分解决了将函数放入 MAX(...) 函数中。所以现在它看起来像:“MAX(FUNCTION('atTimezone', p.startDate, :timezone)), "

标签: spring hibernate spring-boot jpa


【解决方案1】:

这里的问题是,在 SQL 中,两个时区参数将是单独的参数,您的数据库(至少是 PostgreSQL)将无法识别它们实际上是相同的值。

为了解决这个问题,你可以给你的函数一个别名,这个别名可以在 GROUP BY 子句中引用。根据 ANSI SQL 和 JPQL,GROUP BY 子句中不允许选择别名。然而,一些数据库方言,如 PostgreSQL、MySQL 和 H2 确实支持它,并且由于组 by 子句中的 Hibernate 5.4.10 别名被传播到这些支持方言的 SQL 查询 (HHH-9301)。

所以而不是:

SELECT FUNCTION('atTimezone', p.startDate, :timezone), SUM(p.energy))
FROM Process p GROUP BY FUNCTION('atTimezone', p.startDate, :timezone)

你可以这样做:

SELECT FUNCTION('atTimezone', p.startDate, :timezone) AS d, SUM(p.energy))
FROM Process p GROUP BY d

我不知道它如何与对象投影 (NEW ReportDay(...)) 一起工作,但这至少应该让你开始。

【讨论】:

    猜你喜欢
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 2011-12-27
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多