加入 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
我有一个结构:
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