简体   繁体   English

JPQL获取最新行

[英]JPQL get most recent rows

Let's say I have the following tables 假设我有以下表格

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

I want to get the most recent profile information for each profile data type. 我想获取每种配置文件数据类型的最新配置文件信息。 In plain SQL this would look something like: 在普通的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

I've tried different variants of the following JPQL query, but can't get it to work. 我尝试了以下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)

Is this query doable in JPA? 此查询在JPA中可行吗?

I'm using EclipseLink as my JPA provider. 我正在使用EclipseLink作为我的JPA提供程序。

The innermost exception I get when I try to run this is 我尝试运行此方法时遇到的最内层异常是

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

Assuming DATE is actually a timestamp that you're not worried about colliding, it seems like your query could be as simple as 假设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)

Are you using a DBMS like an older MySQL that hates subselects? 您是否正在使用像较早的MySQL那样讨厌子选择的DBMS?

I am also thinking that perhaps your problem is you haven't mapped the object relationship from MyProfileData to ProfileData, and all you have is the actual integer value of the field. 我还认为,也许您的问题是您尚未将对象关系从MyProfileData映射到ProfileData,而您所拥有的只是该字段的实际整数值。 This will make writing JPQL queries quite hard in general. 通常,这将使编写JPQL查询变得相当困难。

Edit: 编辑:

Continuing on the assumption that the dates don't collide for any given profile + profile data type combo, (so date uniquely identifies a row within the subset of a particular profile + profile type combination) you can just grab all the dates: 继续假设日期不会因任何给定的配置文件+配置文件数据类型组合而发生冲突(因此日期唯一地标识特定配置文件+配置文件类型组合的子集中的一行),您可以获取所有日期:

    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)

Your original SQL example isn't actually legal, so it's tough to come up with a way to reproduce what it looks like it's trying to do without having a way to uniquely identify the rows while excluding the value. 您最初的SQL示例实际上是不合法的,因此很难想出一种方法来重现其尝试执行的操作,而又没有一种方法来唯一地标识行而不排除值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM