为了账号安全,请及时绑定邮箱和手机立即绑定

Laravel中三个表的复杂查询

Laravel中三个表的复杂查询

PHP
呼如林 2021-05-06 16:22:16
我有一个Laravel无法解决的问题。我有三个表:用户,属性,优惠用户具有许多属性和要约属性和要约属于用户Properties table:iduser_idcontract_start_dateother_date…created_atupdated_atOffers table:iduser_id…created_atupdated_at我想给一个这样的表(我使用两个日期过滤器:startDate和endDate):Users name || Properties count (They are filtered by contract_start_date)  || Properties count (They are filtered by other_date) || Offers count———user1 || 5 || 2 || 12user2 || 0 || 1 || 0user3 || 0 || 0 || 0…我尝试使用union,leftJoin等,但是我无法解决此问题……谢谢,如果可以的话
查看完整描述

1 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

快速与肮脏

首先,让您的用户渴望加载其属性的日期和所有报价。


$users = Users::with([

    'property'=>function($query){

        $query->select('contract_startdate','otherdate');

    },

    'offer'=>function($query){

        $query->select('id');

    },

);

假设您已$dates在模型中正确设置数组以包含contract_startdate和other_date。我们可以使用碳来过滤集合,以获得我们感兴趣的属性。在您看来,您可以:


<table>

  <thead>

     <tr>

       <th>User</th>

       <th>Property (start date)</th>

       <th>Property (other date)</th>

       <th>Offers</th>

     </tr>

   </thead>

   <tbody>          

   @foreach($users as $user)

       <tr>

           <td>{{$user->name}}</td>

           <td>{{$user->properties

               ->filter(function($item) use ($filter_start,$filter_end){

                   return $item->contract_startdate->between($filter_start,$filter_end);

               })->count() }}</td>

           <td>{{$user->properties

               ->filter(function($item) use ($filter_start,$filter_end){

                   return return $item->other_date->between($filter_start,$filter_end);

               })->count() }}</td>

           <td>{{$user->offers->count()}}</td>

       </tr>

   @endforeach

   </tbody>

</table>

清理

您可能应该将过滤器从视图中重构出来以保持整洁,但是这样做会在集合上添加另一个循环。但是您可以通过在控制器中执行类似的操作来删除循环。


$users = Users::with([

    'property'=>function($query){

        $query->select('contract_startdate','otherdate');

    },

    'offer'=>function($query){

        $query->select('id');

    },

);


$byContractDate = collect();

$byOtherDate = collect();


foreach($users as $user){

    foreach($properties as $property){

        $contractCounter = 0;

        $otherCounter = 0;

        if($propery->contract_startdate->between($filter_start,$filter_end){

             $contractCounter++;

        }

        if($propery->contract_startdate->between($filter_start,$filter_end){

             $otherCounter++;

        }

    }

    $byContractDate->put($user->id,$contractCounter);

    $byOther->put($user->id,$otherCounter);

}

在您看来:


<table>

  <thead>

     <tr>

       <th>User</th>

       <th>Property (start date)</th>

       <th>Property (other date)</th>

       <th>Offers</th>

     </tr>

   </thead>

   <tbody>          

   @foreach($users as $user)

       <tr>

           <td>{{$user->name}}</td>

           <td>{{$byContract->get($user->id)}}</td>

           <td>{{$byOther->get($user->id)}}</td>

           <td>{{$user->offers->count()}}</td>

       </tr>

   @endforeach

   </tbody>

</table>


查看完整回答
反对 回复 2021-05-14
  • 1 回答
  • 0 关注
  • 220 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号