CriteriaAPI predicate :在一列上分组,在另一列上查找行min,然后返回第三行

q1qsirdb  于 2021-06-27  发布在  Java
关注(0)|答案(1)|浏览(447)

我有一张table

CREATE TABLE stp2_vehicles.can_data (
    id bigserial NOT NULL,
    receive_time timestamp NOT NULL,
    gps_frame_id int8 NULL
);

在此基础上,我需要添加更大查询所需的条件 predicate 。在这里,我需要的是选择返回can数据的id—每个gps帧只有一个id—具有最早时间戳的id。
所以在sql中它看起来是这样的:

select cd.id 
from stp2_vehicles.can_data cd
right join
        (select gps_frame_id, min(receive_time) as min_time
        from stp2_vehicles.can_data
        group by gps_frame_id
        ) cd2 on cd.gps_frame_id = cd2.gps_frame_id and cd.receive_time = cd2.min_time
;

不幸的是,criteriaapi不支持与子查询的结果连接。
我也尝试过使用自连接的方法(应该得到criteria api的支持),但我提供的解决方案在计算上似乎过于复杂,或者有我看不到的错误:

select cd.id
from stp2_vehicles.can_data cd
inner join stp2_vehicles.can_data cd2 on cd.id=cd2.id
where cd.receive_time = (select min(receive_time) from stp2_vehicles.can_data cd3 where cd.gps_frame_id = cd3.gps_frame_id );

顺便说一句:我设法解决了更简单的问题:

select min(cd.id) from can_data cd group by cd.gps_frame_id
CriteriaQuery<CANData> criteriaQueryCanData = cb.createQuery(CANData.class);
Subquery<Long> subquery = criteriaQueryCanData.subquery(Long.class);
Root<CANData> canDataSubRoot = subquery.from(CANData.class);
subquery
    .select(cb.least(canDataSubRoot.<Long>get(CANData_.ID)))
    .groupBy(canDataSubRoot.<Long>get(CANData_.GPS_FRAME));
5jdjgkvh

5jdjgkvh1#

因为子查询看起来是“静态的”,所以可以使用 @Subselect 注解。

相关问题