具有最大值的实体的HQL查询

rjs*_*ang 31 java hibernate hql

我有一个看起来像这样的Hibernate实体(为了简洁省略了访问器):

@Entity
@Table(name="FeatureList_Version")
@SecondaryTable(name="FeatureList",
    pkJoinColumns=@PrimaryKeyJoinColumn(name="FeatureList_Key"))
public class FeatureList implements Serializable {

    @Id
    @Column(name="FeatureList_Version_Key")
    private String key;

    @Column(name="Name",table="FeatureList")
    private String name;

    @Column(name="VERSION")
    private Integer version;

}
Run Code Online (Sandbox Code Playgroud)

我想制作一个HQL查询来检索FeatureList的最新版本.以下查询排序:

Select f.name, max(f.version) from FeatureList f group by f.name
Run Code Online (Sandbox Code Playgroud)

问题是不会填充关键字段,我需要包含具有给定FeatureList的最高版本号的记录的键.如果我在select中添加f.key它将无法工作,因为它不在group by或聚合中,如果我把它放在组中,整个停止工作,它只是给我每个版本作为一个单独的实体.

那么,任何人都可以帮忙吗?

axt*_*avt 60

这个查询的简单版本看起来像这样(假设(name, version)对是唯一的):

select f from FeatureList f 
where f.version = 
     (select max(ff.version) from FeatureList ff where ff.name = f.name)
Run Code Online (Sandbox Code Playgroud)


Ade*_*ari 13

我在这里做了一个场景,


key          name                 version         
----------- -------------------- ----------- 
1           adeel                1           
2           adeel                2           
3           adeel                3           
4           ahmad                1           
5           ahmad                2           
6           ahmad                3           
7           ahmad                4           
8           ansari               1           
9           ansari               2           
10          ansari               3           
Run Code Online (Sandbox Code Playgroud)

使用原始查询的结果

>> select f.name, max(f.version) from FeatureList f group by f.name

name                 max(f.version) 
-------------------- ------------ 
adeel                3            
ahmad                4            
ansari               3            
Run Code Online (Sandbox Code Playgroud)

结果使用您想要的查询

>> select fl.* from FeatureList fl 
   where (fl.name, fl.version) in (select f.name, max(f.version) 
                                           from FeatureList f group by f.name);

key          name                 max(fl.version)  
----------- -------------------- ----------- 
3           adeel                3           
7           ahmad                4           
10          ansari               3           
Run Code Online (Sandbox Code Playgroud)

注意:这次尝试使用MySQL.它的工作.我很确定MS SQL Server也有IN (...)运营商.你只需要session.createNativeQuery()在Hibernate中使用.


编辑在axtavt的答案上工作

我们发现这可以简单,

select f from FeatureList f 
where f.version = 
     (select max(ff.version) from FeatureList ff where ff.name = f.name)
Run Code Online (Sandbox Code Playgroud)

现在尝试使用Hibernate Criteria API,

DetachedCriteria versions = DetachedCriteria.forClass(FeatureList.class, "f")
    .setProjection( Property.forName("f.version").max())
    .add(Property.forName("f.name").eqProperty("fl.name"));

session.createCriteria(FeatureList.class, "fl")
    .add( Property.forName("fl.version").eq(versions) )
    .list();
Run Code Online (Sandbox Code Playgroud)


Mar*_*nna 8

老问题,但我想我也会在这里为未来的用户提供我的经验:

select f from FeatureList f where f.version = 
 (select max(ff.version) from FeatureList ff where ff.name = f.name);
Run Code Online (Sandbox Code Playgroud)

这很好用,但如果满足以下条件:

  • MySql v5.5 w/InnoDB引擎
  • 你确切知道你想要多少行结果(OC暗示他/她只需要1行,但上面的查询可以用于不同数量的结果)

以下似乎非常快:

FROM FeatureList ORDER BY version DESC LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

我对表中700,000条记录的类似查询的试验在前一版本中大约需要0.19秒,而后者需要0.05秒.