jOOQ中派生表的相关性

问题描述

我有一个简单的父-子(一对多相关)表。这是我跟踪火车及其位置的简化示例。

Table TRAIN
    - ID
    - NAME
Table TRAIN_STATUS
    - ID
    - TRAIN_ID (fk)
    - STATION_CD
    - ARRIVAL_TIME 

每次火车到达车站时,都会在 TRAIN_STATUS 中插入一条新记录,并带有相应的 STATION_CD 和 ARRIVAL_TIME(时间戳)

给定火车 ID,我希望能够知道火车的最后一个已知车站是什么:

sql 解决方案: - 结合使用派生表和相关子查询

select t.ID,t.name,recent.STATION_CD
from TRAIN t
join (
        select TRAIN_ID,STATION_CD
        from TRAIN_STATUS ts
        where ts.ARRIVAL_TIME = (
            select MAX(ARRIVAL_TIME) from TRAIN_STATUS where TRAIN_STATUS.TRAIN_ID = ts.TRAIN_ID
        )
) recent on t.ID=recent.TRAIN_ID
where t.ID = 1;

我无法在 jOOQ 中组合一个等效项。任何帮助将不胜感激。

编辑:方言是 MysqL (5.7)。发布我自己的答案@LukasEder 的建议。

解决方法

您可以使用如下解析函数简化您的 sql 解决方案并在 jooq 中使用:

select ID,name,station_cd from
(select t.ID,t.name,ts.STATION_CD,row_number() over (partition by t.TRAIN_ID order by ts.ARRIVAL_TIME desc) as rn
  from train t join TRAIN_STATUS ts on t.TRAIN_ID = ts.TRAIN_ID) t
where rn = 1
,
TrainStatus ts = TRAIN_STATUS.as("TS");

SelectConditionStep<Record1<LocalDateTime>> lastArrivalTime = dslContext
        .select(max(TRAIN_STATUS.ARRIVAL_TIME))
        .from(TRAIN_STATUS)
        .where(TRAIN_STATUS.TRAIN_ID.eq(st.TRAIN_ID));

Table<Record2<Long,String>> recent = dslContext
        .select(ts.field(TRAIN_STATUS.TRAIN_ID),ts.field(TRAIN_STATUS.STATUS_CD))
        .from(ts)
        .where(ts.field(TRAIN_STATUS.ARRIVAL_TIME).eq(lastArrivalTime))
        .asTable("recent");

return dslContext
        .select(
                TRAIN.TRAIN_ID.as("id"),recent.field(TRAIN_STATUS.STATUS_CD).as("recent_status_code")
        )
        .from(TRAIN)
        .join(recent).on(TRAIN.TRAIN_ID.eq(recent.field(TRAIN_STATUS.TRAIN_ID)))
        .where(TRAIN.ID.eq(1)) 
        .fetchOneInto(TrainStatusModel.class);