将SQL查询转换为休眠标准和预测

时间:2018-05-21 11:39:42

标签: sql-server hibernate subquery hql hibernate-criteria

我从SQL查询:

select e.* 
from terminal_remote_deployment e
where id = (select top 1 e1.id
            from terminal_remote_deployment e1
            where e1.Terminal_info_id = e.Terminal_info_id
            order by e1.version desc
           );

我正在尝试用HQL编写它:

final StringBuilder hql = new StringBuilder();
            hql.append(" from TerminalRemoteDeployment e");
            hql.append(" where e.id = (Select TOP 1 e1.id from TerminalRemoteDeployment e1 where e1.terminalInfo.id = e.terminalInfo.id order by e1.version desc)");

            Query query = getEntityManager().createQuery(hql.toString());
            resultList = (List<TerminalRemoteDeployment>) query.getResultList();

我遇到这种方法的错误。请帮我写一下hibernate的标准,因为我对此很新。

4 个答案:

答案 0 :(得分:3)

第二个附加内部子查询中的Where子句。 它应该是 terminal_Info_id 而不是 terminalInfo.id

final StringBuilder hql = new StringBuilder();
        hql.append(" from TerminalRemoteDeployment e");
        hql.append(" where e.id = (Select TOP 1 id from TerminalRemoteDeployment e1 where e1.terminal_Info_id = e.terminal_Info_id order by e1.version desc)");

        Query query = getEntityManager().createQuery(hql.toString());
        resultList = (List<TerminalRemoteDeployment>) query.getResultList();

答案 1 :(得分:3)

正如评论中已经说过的那样,使用setMaxResult()方法代替TOP关键字,因为HQL不支持该方法。

同样在sub-select您正在使用id而没有它的实体别名。

将其更改为Select e1.id from TerminalRemoteDeployment e1

答案 2 :(得分:3)

首先,我不是Hibernate的专家。但是你的第一个查询是否特定于SQL Server:

select e.* 
from terminal_remote_deployment e
where id = (select top 1 e1.id
            from terminal_remote_deployment e1
            where e1.Terminal_info_id = e.Terminal_info_id
            order by e1.version desc
           );

我会使用ROW_NUMBER重写它(由MySQL 8.0 / MariaDB / SQL Server / PostgreSQL / Oracle / H2 / Derby / ...支持)然后我会使用命名查询:

SELECT *
FROM(SELECT e.*,
     ROW_NUMBER() OVER(PARTITION BY Terminal_info_id ORDER BY version desc) AS rn
     FROM terminal_remote_deployment e) sub
WHERE rn = 1;

答案 3 :(得分:1)

你是否想要这样做。

select e.* 
from  terminal_remote_deployment e1 JOIN 
      (select e.id, max(e.version)
      from terminal_remote_deployment e group by e.id) as a
on e.id = a.id