JPA 为每个项目选择最新实例

2022-09-01 18:37:40

假设我有一个会议实体。每个会议都有一个与会者和一个会议日期。在我的会议表中,我可能为每个与会者设置多个会议,每个会议的日期不同。我需要一个 JPA 查询,该查询将仅为所有与会者选择最新的会议。例如,如果我的表看起来像这样

Meeting ID | Attendee ID | Meeting Date
1          | 1           |  6/1/2011
2          | 2           |  6/1/2011
3          | 1           |  6/6/2011
4          | 3           |  6/6/2011

我的结果应该是

Meeting ID | Attendee ID | Meeting Date
2          | 2           |  6/1/2011
3          | 1           |  6/6/2011
4          | 3           |  6/6/2011

使用 JPA 2 对抗 postgres。会议有 1-1 到与会者和一个简单的时间戳日期。我怀疑我需要做一个小组和max(blah),也许可以加入自己,但我不确定解决这个问题的最佳方法。

更新:在花了一整晚的时间玩这个之后,我仍然没有一个可接受的JPQL解决方案。以下是我到目前为止所拥有的:

select m from Meeting m 
where m.meetingDate in 
    ( select max(meet.meetingDate) 
      from Meeting meet group by meet.attendee )

我有各种与这个问题无关的其他条件,例如按与会者部门过滤等等。这有效的唯一原因是,我们将会议日期跟踪到第二个(或更精细),并且在同一时间有两个会议的可能性很小。我们正在围绕它放置一些java的东西,以便只保留每个与会者的最后一次会议,以防万一我们同时得到两个,但这是一个非常糟糕的解决方案。在查询中获取所有内容确实不应该太困难,但我还没有弄清楚。

更新2:添加sql标签,因为如果我需要使用sql来创建视图并创建一个JPA对象来映射到视图,我对此感到满意。


答案 1

在 SQL 中,解决方案非常简单 - 使用子查询联接表,该子查询可为您提供每个与会者的最新会议:

select * from Meeting ALL
join ( select max(meetingDate) as newest, attendee
from Meeting group by attendee ) LATEST
on ALL.meetingDate = LATEST.newest AND ALL.attendee = LATEST.attendee

这有效,并且工作速度很快!

JPA的问题在于它(或大多数实现)不允许连接子查询。在花了几个小时尝试了最初编译的内容之后,然后,它有多慢,我决定我讨厌JPA。像上面的解决方案 - 如 EXISTS (SELECT .. ) 或 IN ( SELECT .. ) - 需要很长时间才能执行,比它们应该慢几个数量级。

拥有一个有效的解决方案意味着我只需要从JPA访问该解决方案。SQL中有两个神奇的词可以帮助你做到这一点:

CREATE VIEW

生活变得如此简单...只需定义这样的实体并使用它。警告:它是只读的。

当然,任何JPA纯粹主义者在你这样做时都会看不起你,所以如果有人有一个纯粹的JPA解决方案,请让我们俩都知道!


答案 2

我想我已经通过这个查询得到了它。

select m from Meeting m 
    where m.meetingDate = 
        (select max(m1.meetingDate) 
            from Meeting m1 
            where m1.attendee = m.attendee )
    and not exists 
        (select m2 from Meeting m2 
            where m2.attendee = m.attendee 
            and m2.meetingDate > m.meetingDate)

推荐