Сложный запрос из трех таблиц в Laravel - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть проблема, которую я не могу решить с помощью Laravel.У меня есть три таблицы:

Пользователи, свойства, предложения

Пользователи имеют много свойств и предложений Свойства и предложения принадлежат пользователю

Properties table:
id
user_id
contract_start_date
other_date
…
created_at
updated_at

Offers table:
id
user_id
…
created_at
updated_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 || 12
user2 || 0 || 1 || 0
user3 || 0 || 0 || 0
…

Я пытаюсь с помощью union, leftJoin и т. д., но я не могу решить эту проблему ... Спасибо, если вы можете помочь

1 Ответ

0 голосов
/ 24 апреля 2019

Быстро и Грязно

Во-первых, заставьте своих пользователей загружать даты их свойств и все предложения.

$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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...