Android Room:扩展SELECT DISTINCT查询获取多列数据需求
解决方案
要获取每个车次的编号(tripNumber)及其首个站点的出发时间戳(stationStart),核心是对每个车次分组后,定位到对应车次的首个站点记录。以下是几种适配你场景的实现方式:
方式一:JPQL分组查询(Spring Data JPA 常用写法)
假设首个站点的出发时间戳(stationStart)是该车次所有站点中最早的,可通过GROUP BY分组车次编号,再用MIN()函数提取最早的时间戳:
@Query("SELECT s.tripNumber, MIN(s.stationStart) FROM Stations s GROUP BY s.tripNumber") List<Object[]> findTripNumberAndFirstStationStart();
- 返回的
Object[]中,第一个元素是车次编号tripNumber,第二个是对应首个站点的stationStart(Long类型) - 若想返回更清晰的结果,可定义DTO类并使用构造函数投影:
// 自定义DTO类 public class TripFirstStationDTO { private String tripNumber; private Long stationStart; public TripFirstStationDTO(String tripNumber, Long stationStart) { this.tripNumber = tripNumber; this.stationStart = stationStart; } // 按需添加getter/setter } // 调整后的查询语句 @Query("SELECT new com.yourpackage.TripFirstStationDTO(s.tripNumber, MIN(s.stationStart)) FROM Stations s GROUP BY s.tripNumber") List<TripFirstStationDTO> findTripNumberAndFirstStationStart();
方式二:按站点顺序精准匹配(若有站点排序字段)
如果表中存在专门标记站点顺序的字段(比如stationOrder,值越小代表站点越靠前),可通过子查询定位每个车次的首个站点:
@Query("SELECT s.tripNumber, s.stationStart FROM Stations s WHERE s.stationOrder = (SELECT MIN(s2.stationOrder) FROM Stations s2 WHERE s2.tripNumber = s.tripNumber)") List<Object[]> findTripNumberAndFirstStationByOrder();
方式三:原生SQL查询(适配复杂场景)
若需要更底层的数据库语法支持,可使用原生SQL查询:
@Query(value = "SELECT trip_number, MIN(station_start) FROM stations GROUP BY trip_number", nativeQuery = true) List<Object[]> findTripNumberAndFirstStationStartNative();
注意替换语句中的表名、字段名为数据库实际使用的原生名称(比如驼峰命名转下划线)。
内容的提问来源于stack exchange,提问作者Konstantin Konopko
相关产品推荐
相关产品推荐

