微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Laravel Eloquent:在主语句上应用“with where”过滤器

如何解决Laravel Eloquent:在主语句上应用“with where”过滤器

问题: 我正在使用 eloquent 从具有特定状态和注册日期值的数据库提取学生。它们也必须仅在子表数据也作为特定列数据时显示。 问题是 Laravel 将其分解为多个查询,而“with”(急切加载)表仅在事后才被过滤。

换句话说,而不是(伪sql):

SELECT all students WHERE 
status IN (1,4,6,7) 
AND (YEAR(registration_date)<=2020 OR YEAR(registration_date) IS NULL) 
AND YEAR(commencement_date)>=2020
AND (YEAR(completion_date)>=2020 OR YEAR(estimated_completion_date)>=2020)

它推出了 4 个单独的 sql 语句(请参阅下面的“结果 sql”),其中仅对学生应用 status/registration_date 过滤器,并单独将其他过滤器向下过滤,导致实际行结果不正确(显示比他们应该的更多)。

我只想使用 DB::table / DB:raw - 但是在刀片端,我无法提取子子数据,因为它不再处于层次结构中。

代码

    DB::enableQueryLog();
    $students = $bursary_administrator->students()->whereIn('status',[1,7])
        ->whereHas('bursaries',function($query) use ($request) {
            $query->whereYear('registration_date','<=',$request->year)
                ->orWhereNull('registration_date');
        })
        ->with(['bursaries','bursaries.enrolments','bursaries.enrolments.courses' => function($query) use ($request) {
            $query->whereYear('commencement_date',$request->year)
                ->where(function ($query) use ($request){
                    $query->whereYear('completion_date','>=',$request->year)
                        ->whereYear('estimated_completion_date',$request->year,'or');
                });
        }])
        ->orderBy('student_name')->orderBy('student_middle_names')->orderBy('student_surname')->get();
    Log::debug(DB::getQueryLog());

结果 sql

local.DEBUG: array (
  0 => 
  array (
    'query' => 'select `students`.*,`bursary_administrator_student`.`bursary_administrator_id` as `pivot_bursary_administrator_id`,`bursary_administrator_student`.`student_id` as `pivot_student_id`,`bursary_administrator_student`.`created_at` as `pivot_created_at`,`bursary_administrator_student`.`updated_at` as `pivot_updated_at` from `students` inner join `bursary_administrator_student` on `students`.`id` = `bursary_administrator_student`.`student_id` where `bursary_administrator_student`.`bursary_administrator_id` = ? and `status` in (?,?,?) and exists (select * from `student_bursaries` where `students`.`id` = `student_bursaries`.`student_id` and (year(`registration_date`) <= ? or `registration_date` is null)) order by `student_name` asc,`student_middle_names` asc,`student_surname` asc','bindings' => 
    array (
      0 => 1,1 => 1,2 => 4,3 => 6,4 => 7,5 => '2020',),'time' => 6.69,1 => 
  array (
    'query' => 'select * from `student_bursaries` where `student_bursaries`.`student_id` in (1,3,14,20,24,25,29,41,42,44,49,51,53,55,56,62,64,65,72,75,76,80,81,85,94,98,100,106,111,112,133,138,139,141,156,157,169,170,180,199,203,210,213,214,217,219,221,224,225,226,227,228,229,231,232,233,234,235,237,238,239,240,242,243,246,249,251,252,253,254,255,256,257,258,260,261,262,263,265,267,268,269,270,271,273,274,275,276,277,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,297,299,300,302,303,304,305,306,307,308,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,333,334,335,336,337,338,339,340,341,343,344,345,346,347,348,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364)','bindings' => 
    array (
    ),'time' => 2.41,2 => 
  array (
    'query' => 'select * from `student_bursary_enrolments` where `student_bursary_enrolments`.`student_bursary_id` in (1,3 => 
  array (
    'query' => 'select * from `student_bursary_enrolment_courses` where `student_bursary_enrolment_courses`.`student_bursary_enrolment_id` in (1,12,18,19,21,22,27,28,38,39,40,43,48,50,52,57,66,67,77,82,93,96,99,104,110,130,134,135,136,152,153,154,164,165,175,181,187,193,194,195,196,200,201,202,204,205,206,209,211,212,215,216,220,222,223,230,241,247,248,259,264,266,278,294,295,296,298,301,309,332,342,349,364,365,366,367,368,369,371,372,373,374,375,376,377,378,379,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,409,411,413,414,415,417,418,419,424,429,431,432,433,436,442,443,445,447,448,450,452,453,456,457,466,467,468,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485) and year(`commencement_date`) <= ? and (year(`completion_date`) >= ? or year(`estimated_completion_date`) >= ?)','bindings' => 
    array (
      0 => '2020',1 => '2020',2 => '2020','time' => 2.85,)  

刀片/视图:

<tbody>
@if ($students)
    @PHP($row_count=0)
    @foreach ($students as $student)
        @PHP($row_count++)
        <tr>
            <td>{{$row_count}}</td>
            <td>{{$student->student_name .' '. $student->student_middle_names .' '. $student->student_surname}}</td>
            <td colspan="4">
                @if ($student->bursaries)
                    <table class="subtable">
                        @foreach ($student->bursaries as $bursary)
                            @if ($bursary->enrolments)
                                @foreach ($bursary->enrolments as $enrolment)
                                    @if ($enrolment->courses)
                                        @foreach ($enrolment->courses as $course)
                                            <tr>
                                                <td>{{$enrolment->academic_institution->academic_institution .' - '. $course->course}}</td>
                                                <td class="f114">{{__($course->current_year)}}</td>
                                            </tr>
                                        @endforeach
                                    @else
                                        <tr><td>Error: No courses</td></tr>
                                    @endif
                                @endforeach
                            @else
                                <tr><td>Error: No enrolments</td></tr>
                            @endif
                        @endforeach
                    </table>
                @else
                    Error: No bursaries
                @endif
            </td>
        </tr>
    @endforeach
@endif

</tbody>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。