【发布时间】:2020-06-15 13:54:39
【问题描述】:
我的 Laravel 应用程序中有以下模型:课程、活动、学生、注册、出勤。
- 一个课程有许多事件。
- 当学生注册课程时,会生成一个 Enrollment,因此课程有Many Enrolments。
- 一个学生有很多出勤记录。
- 出勤记录属于活动和学生。
我想检索至少有一名学生的出勤记录少于课程中预期事件总数的课程列表。例如,如果一门课程有 10 个活动,我需要获取所有课程,其中至少有一名学生的出勤记录少于这些活动的 10 个预期出勤记录。
作为临时解决方案,我在课程模型中使用了嵌套的 foreach 循环:
public function getEventsWithExpectedAttendanceAttribute()
{
return $this->events()->where(function($query) {
$query->where('exempt_attendance', '!=', true);
$query->where('exempt_attendance', '!=', 1);
$query->orWhereNull('exempt_attendance');
})->where('start', '<', Carbon::now(env('COURSES_TIMEZONE'))->toDateTimeString())->get();
}
public function getMissingAttendanceAttribute()
{
$eventsWithMissingAttendanceCount = 0;
// loop through every event supposed to have attendance
foreach ($this->events_with_expected_attendance as $event)
{
// loop through every student
foreach ($this->enrollments as $enrollment)
{
// if the student has no attendance record for this event
if (Attendance::where('student_id', $enrollment->student_id)->where('event_id', $event->id)->count() == 0)
{
// count one and break loop
$eventsWithMissingAttendanceCount++;
break;
}
}
}
return $eventsWithMissingAttendanceCount;
}
但这真的不漂亮,而且在性能方面也非常低效。但是,到目前为止,我一直无法找到更好的解决方案。任何帮助将不胜感激!
更新:这里是数据库架构
CREATE TABLE `courses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`));
CREATE TABLE `events` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`course_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `enrollments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`student_id` int(10) unsigned NOT NULL,
`course_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `students` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`));
CREATE TABLE `attendances` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`student_id` int(10) unsigned NOT NULL,
`event_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`));
【问题讨论】:
-
如果是我,我会从 sql 开始。如果这听起来是一个合理的想法,请删除上面的内容并改为查看 meta.stackoverflow.com/questions/333952/…
-
我在这里同意草莓。这应该可以在sql中解决。您可以添加表格方案,让想要回答的人更容易。
-
我明白了,也许 sql 确实是一个更好的选择。我用信息更新了我的问题,以重现类似于我的数据库的简化模式。
标签: php mysql laravel optimization eloquent