问题描述
我有一个简单的父-子(一对多相关)表。这是我跟踪火车及其位置的简化示例。
Table TRAIN
- ID
- NAME
Table TRAIN_STATUS
- ID
- TRAIN_ID (fk)
- STATION_CD
- ARRIVAL_TIME
每次火车到达车站时,都会在 TRAIN_STATUS 中插入一条新记录,并带有相应的 STATION_CD 和 ARRIVAL_TIME(时间戳)
给定火车 ID,我希望能够知道火车的最后一个已知车站是什么:
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);