加入 table 并在那里找到 min/max(Collection)

Join table and find there min/max(Collection)

我有一个结构:

public class ChosenCourseDate {

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name="chosencoursedate_id")
    List<ChosenCourseDatePeriod> chosenCourseDatePeriod;
}

public class ChosenCourseDatePeriod {

    Date startDateTime;
    Date endDateTime;

    @ManyToOne
    @JoinColumn(name="chosencoursedate_id")
    ChosenCourseDate chosenCourseDate;
}

我想在现有的 select 语句中添加一个新条件,以在 ChosenCourseDatePeriod 中最早的 startDateTime 找到 objects。

1)Select 语句:

select registration from CourseRegistration registration
left join registration.chosenCourseDate as chosencoursedate
left join chosencoursedate.chosenCourseDatePeriod as period
where registration.candidate =:candidate
and registration.course =:course
and min(period.startDateTime) >=:now;

结果:

Invalid use of group function

2)Select 语句:

select registration, min(period.startDateTime) as earliestDate from CourseRegistration registration
left join registration.chosenCourseDate as chosencoursedate
left join chosencoursedate.chosenCourseDatePeriod as period
where registration.candidate =:candidate
and registration.course =:course
and earliestDate >=:now;

结果:

Unknown column 'earliestDate' in 'where clause', cause: null

3) 我决定使用 2 个 SELECT 语句,这很有帮助。

select registration from CourseRegistration registration
    left join registration.chosenCourseDate as chosencoursedate
    where registration.candidate =:candidate
    and registration.course =:course
    and (SELECT min(period.startDateTime) FROM ChosenCourseDate inChosenCourseDate join inChosenCourseDate.chosenCourseDatePeriod period where inChosenCourseDate = chosenCourseDate) >=:now;

我的第一个和第二个解决方案有什么问题?是否可以只做一个 SELECT ?

您不能在 WHERE 子句上或没有 GROUP BY 子句的情况下使用聚合函数。如果要检查最大日期,请添加 GROUP BY 子句并使用 HAVING 作为聚合函数的条件:

SELECT registration
FROM CourseRegistration registration
LEFT JOIN registration.chosenCourseDate chosencoursedate
LEFT JOIN chosencoursedate.chosenCourseDatePeriod period
WHERE registration.candidate =:candidate
  AND registration.course =:course
GROUP BY registration
HAVING min(period.startDateTime) >=:now;

您的第二个查询也无效,它只适用于旧版本的 MySQL ,因为您缺少 GROUP BY 子句。另一个原因是 - 你不能在创建它的同一层中使用派生列(你制作的列),所以解决方案是用另一个 select:

包装它
SELECT * FROM ( Your query... ) // It is not available inside the query
WHERE earliestDate>=:now; // It is now available