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

2022-09-01 08:03:50

我有一个如下所示的休眠实体(为简洁起见,省略了访问器):

@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;

}

我想创建一个检索最新版本的功能列表的 HQL 查询。以下查询排序的工作原理:

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

麻烦的是,它不会填充键字段,我需要包含具有给定 FeatureList 最高版本号的记录的键。如果我在选择中添加f.key它将不起作用,因为它不在组或聚合中,如果我按整个事物将其放入组中,它将停止工作,它只是将每个版本作为一个单独的实体。

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


答案 1

此查询的简单版本如下所示(假设对是唯一的):(name, version)

select f from FeatureList f 
where f.version = 
     (select max(ff.version) from FeatureList ff where ff.name = f.name)

答案 2

我在这里做了一个场景,


桌子

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           

使用原始查询的结果

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

name                 max(f.version) 
-------------------- ------------ 
adeel                3            
ahmad                4            
ansari               3            

使用所需查询的结果

>> 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           

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


编辑以处理axtavt的答案

正如我们发现的那样,这可以变得简单如下:

select f from FeatureList f 
where f.version = 
     (select max(ff.version) from FeatureList ff where ff.name = f.name)

现在尝试使用休眠标准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();

推荐