【问题标题】:How to call SQL query with aggregate function in JPA/Hibernate如何在 JPA/Hibernate 中使用聚合函数调用 SQL 查询
【发布时间】:2013-02-27 01:14:27
【问题描述】:

是否可以在 JPA/Hibernate 中运行如下这样的查询?

select v.country,
v.site,
    SUM(case when s.id = 1 then 1 else 0 end) as Total_SuspectedViolations,
    SUM(case when s.id = 2 then 1 else 0 end) as Total_ConfirmedViolations,
    SUM(case when s.id = 3 then 1 else 0 end) as Total_ConfirmedNoViolations,
    SUM(case when s.id = 4 then 1 else 0 end) as Total_NotDetermined,
    COUNT(*) Total
from violations v
inner join status s
    on v.status_id = s.id
group by v.country, v.site

select v.country,
v.site,
    SUM(case when v.status_id = 1 then 1 else 0 end) as Total_SuspectedViolations,
    SUM(case when v.status_id = 2 then 1 else 0 end) as Total_ConfirmedViolations,
    SUM(case when v.status_id = 3 then 1 else 0 end) as Total_ConfirmedNoViolations,
    SUM(case when v.status_id = 4 then 1 else 0 end) as Total_NotDetermined,
    COUNT(*) Total
from violations v
group by v.country, v.site

这在 Oracle DB 中有效,但是当我使用 JPA/Hibernate 时,我得到:

ERROR [PARSER] line 1:311: unexpected token: total
ERROR [PARSER] line 1:375: unexpected token: ON

我之所以这么问,是因为我需要根据一张“违规”表中的数据实现一些简单的统计数据

以下是我的想法:

我需要连接两个表并计算第二个表中的一些值的出现次数,以达到类似于统计表的效果,该表将具有列:

结果表:

  • 国家/地区 varchar(20),
  • 站点 varchar(20),
  • suspected_violation long,
  • confirmed_violation long,
  • confirmed_no_violation long,
  • not_determined long,
  • 总长

我的结果表需要有前两列(contry 和 site)来自第一个表“Violations”,接下来的 5 列将包含每个可能的 id 值中“Violations”中 status_id 出现次数(计数)状态表。

所以,我有两个表:Violations 和 Status。

违规:

  • id 长,
  • 国家/地区 varchar(20),
  • 站点 varchar(20),
  • status_id long,
  • ...在这种情况下其他不重要的列

状态:

  • id 长,
  • 状态长 “状态”列的值 (1-4) 映射到字符串值:疑似违规 (1)、确认违规 (2)、确认无违规 (3)、未确定 (4)

我加入的结果是有一个应该包含列的表:

  • 来自违规表:“国家/地区”和“网站”
  • 来自状态表:“怀疑违规”、“确认违规”、“确认无违规”、“未确定”、“总计”(其中此列是违规表中出现的计数器)。

更新:据我所知,现在不需要使用连接,查询只能在一张表上运行。

您能否建议我在 JPA/Hibernate 中执行此操作的正确方法是什么?

【问题讨论】:

  • 在 JPA 中你可以使用 createNativeQuery

标签: java sql hibernate jpa


【解决方案1】:

你必须使用

session.createSQLQuery 

并且可以使用下面的方法将sql结果转换为你需要的bean

query.setResultTransformer(Transformers.aliasToBean(YourBean.class))

或者你可以使用Projections

【讨论】:

    【解决方案2】:

    感谢您的建议,同时我已经以这种方式解决了它:

    List<ViolationSummaryDTO> result = em.createQuery(
                    "SELECT new ViolationSummaryDTO(v.counName, v.siteNumber," +
                        "sum(case when v.pvClStati.clstId = 1 then 1 else 0 end) as suspectedViolation," +
                        "sum(case when v.pvClStati.clstId = 2 then 1 else 0 end) as confirmedViolation," +
                        "sum(case when v.pvClStati.clstId = 3 then 1 else 0 end) as confirmedNoViolation," +
                        "sum(case when v.pvClStati.clstId = 0 then 1 else 0 end) as notDetermined," +
                        "COUNT(*) as total)" +
                    " FROM Violation v" +
                    " WHERE v.trial.id = " + trialId +
                    " GROUP BY v.counName, v.siteNumber", ViolationSummaryDTO.class).getResultList();
    

    result 是 hibernate 在 SELECT new 语句中创建的对象列表。

    【讨论】:

      猜你喜欢
      • 2011-02-24
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      相关资源
      最近更新 更多