JPQL получить самые последние строки - PullRequest
2 голосов
/ 03 мая 2010

Допустим, у меня есть следующие таблицы

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 голосов
/ 09 июня 2010

Я отказался от попыток создать этот запрос в JPA и вместо этого написал собственный запрос

0 голосов
/ 03 мая 2010

Если предположить, что 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, который ненавидит подвыборы?

Я также думаю, что, возможно, ваша проблема в том, что вы не отобразили отношение объекта из MyProfileData в ProfileData, и все, что у вас есть, - это фактическое целочисленное значение поля. В общем, это затруднит написание JPQL-запросов.

Edit:

Продолжая исходить из предположения, что даты не совпадают для какого-либо конкретного профиля + комбинированный тип данных профиля (таким образом, дата однозначно определяет строку в подмножестве определенной комбинации профиль + тип профиля), вы можете просто захватить все даты :

    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 на самом деле недопустим, поэтому сложно придумать способ воспроизвести то, на что он похож, что пытается сделать, без способа уникальной идентификации строк, исключая значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...