Сравните данные отношений с родительскими данными - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть эти модели и соответствующие им таблицы в базе данных:

  • Заказать
  • ConstructionSite
  • 1008 * рабочих часов *

Заказ hasOne ConstructionSite, который в свою очередь hasMany Рабочие часы.

В моей таблице orders У меня есть столбец installation_planned_in_hours, а в моей таблице working_hours У меня есть столбец worked_hours.

Каков наилучший и более эффективный способ получения всех заказов, общее количество которых worked_hours (помните Order-> ConstructionSite-> WorkingHours) составляет не менее 80% от installation_planned_in_hours?


РЕДАКТИРОВАТЬ 1:

Практический пример:

Order:
- id => 10001
- installation_planned_in_hours => 100

ConstructionSite:
- id => 1
- order_id => 10001

WorkingHours:
- id => 1
- construction_site_id => 1
- worked_hours => 5

- id => 2
- construction_site_id => 1
- worked_hours => 7

- id => 3
- construction_site_id => 1
- worked_hours => 8

Зная, что мои Модели имеют следующие отношения:

class Order extends Model
{
  public function constructionSite()
  {
    return $this->hasOne('App\ConstructionSite');
  }
}

class ConstructionSite extends Model
{
  public function order()
  {
    return $this->belongsTo('App\Order');
  }

  public function workingHours()
  {
    return $this->hasMany('App\WorkingHours');
  }
}

class WorkingHours extends Model
{
  public function constructionSite()
  {
    return $this->belongsTo('App\ConstructionSite');
  }
}

Так, как я могу эффективно проверить, является ли worked_hours ConstructionSite, связанный с конкретным Заказом, выше или ниже 80% от installation_planned_in_hours?

заказа?

Точнее, скажем, у меня больше записей в моей базе данных (больше заказов, строительных площадок и рабочего времени) Как я могу выполнить что-то вроде этого:

$orders = Order::where('sum(constructionSite.workingHours.worked_hours)', '>', '80% of installation_planned_in_hours')->get();

РЕДАКТИРОВАТЬ 2:

Я придумал это решение:

$orders = \App\Order::with('constructionSite.workingHours')->has('constructionSite.workingHours')
  ->leftJoin('construction_sites', 'construction_sites.order_id', '=', 'orders.id')
  ->select('orders.*', 'construction_sites.*', 'construction_sites.id as csid')
  ->leftJoin('working_hours', 'working_hours.construction_site_id', '=', 'construction_sites.id')
  ->selectRaw('sum(working_hours.worked_hours) as tot_whs')
  ->groupBy('working_hours.construction_site_id')
  ->havingRaw('sum(working_hours.worked_hours) > orders.installation_planned_in_hours * 0.8')
  ->get();

Но действительно ли это самый хороший и эффективный способ?

1 Ответ

0 голосов
/ 26 апреля 2018

Вы можете использовать это:

class Order extends Model
{
    public function workingHours()
    {
        return $this->hasManyThrough(WorkingHours::class, ConstructionSite::class);
    }
}

$orders = Order::whereHas('workingHours', function($query) {
    $query->select(DB::raw('SUM(worked_hours) total'))
        ->having('total', '>', DB::raw('0.8 * installation_planned_in_hours'));
})->get();
...