Java JPQL获取最近的行

Java JPQL获取最近的行,java,jpa,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:

假设我有以下表格

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

假设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)
您使用的DBMS是否像旧的MySQL一样讨厌子选择

我还认为,您的问题可能是您没有将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示例实际上是不合法的,因此很难找到一种方法来重现它试图执行的操作,而不需要一种方法来唯一地标识行,同时排除值。

假设日期实际上是一个时间戳,您不担心发生冲突,您的查询似乎可以简单到

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)
您使用的DBMS是否像旧的MySQL一样讨厌子选择

我还认为,您的问题可能是您没有将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示例实际上并不合法,因此,很难找到一种方法来重现它试图执行的操作,而不需要在排除值的同时唯一地标识行。

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

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

My令人不快的我试图简化我的例子,但我认为我把它简化得太多了。查询还有另一个维度-profile_data_type-缺少该维度,这是需要分组依据的维度。增加了问题描述…我的错。我试图简化我的例子,但我认为我把它简化得太多了。查询还有另一个维度-profile_data_type-缺少该维度,这是需要分组依据的维度。添加到问题描述…这应该是一个评论。这应该是一个评论。