JPQL获取最新的行

时间:2010-05-03 15:19:26

标签: java jpa

假设我有以下表格

my_profile_data
-------------
integer: my_profile_data_id
integer: profile_id
integer: profile_data_type_id
date: date_changed
string: value

my_profile
-------------
integer: profile_id
string: name

profile_data_type
-------------
integer: profile_data_type_id
string: name

我想获取每种配置文件数据类型的最新配置文件信息。在纯SQL中,这看起来像:

select mpd.profile_id, mpd.profile_data_type_id, mpd.value, max(mpd.date_changed) 
from my_profile_data mpd, my_profile mp 
where mpd.profile_id = mp.profile_id and mp.name='The Profile I Want' 
group by mpd.profile_data_type_id

我尝试了以下JPQL查询的不同变体,但无法使其工作。

SELECT mpd FROM MyProfileData mpd LEFT JOIN
     (SELECT mpd.profileId profileId, MAX(mpd.dateChanged) FROM MyProfileData mpd
     LEFT JOIN mp.profile
     WHERE mp.name = :name
     GROUP BY mpd.profileDataTypeId) recent
ON (rp.profileid = recent.profileId)

此查询在JPA中是否可行?

我正在使用EclipseLink作为我的JPA提供程序。

我尝试运行时遇到的最内层异常是

Caused by: NoViableAltException(81!=[506:7: (n= joinAssociationPathExpression ( AS )? i= IDENT | t= FETCH n= joinAssociationPathExpression )])
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.join(JPQLParser.java:3669)
    ... 73 more

2 个答案:

答案 0 :(得分:0)

假设DATE实际上是一个您不担心碰撞的时间戳,看起来您的查询可能就像

一样简单
select mpd 
from MyProfileData mpd
where mpd.profile.name = :name
and mpd.date = (select max(mpd1.date) from MyProfileData mpd1 where mpd1.profile.name = :name)

您是否正在使用像旧版MySQL这样讨厌子选择的DBMS?

我也在想,也许你的问题是你没有将对象关系从MyProfileData映射到ProfileData,你所拥有的只是该字段的实际整数值。这将使编写JPQL查询变得非常困难。

编辑:

继续假设日期不会因任何给定的配置文件+配置文件数据类型组合而发生冲突(因此日期唯一标识特定配置文件子集中的行+配置文件类型组合),您可以抓住所有日期:

    select mpd from MyProfileData
    where mpd.profile.name = :name
    and mpd.date in (select max(mpd1.date) 
                     from MyProfileData mpd1 
                     where mpd1.profile = mpd.profile group by mpd.profileDataType)

你原来的SQL示例实际上并不合法,所以很难想出一种方法来重现它正在尝试做的事情而没有办法在排除值时唯一地识别行。

答案 1 :(得分:0)

我放弃了尝试在JPA中创建此查询并编写了一个本机查询

相关问题