将关系数据与父数据进行比较

时间:2018-04-25 07:41:53

标签: php laravel eloquent laravel-5.2 laravel-query-builder

我在数据库中有这些模型及其相应的表格:

  • 顺序
  • ConstructionSite
  • WorkingHours

订单hasOne ConstructionSite,反过来hasMany WorkingHours。

在我的表orders中,我有一列installation_planned_in_hours,在我的表working_hours中,我有一列worked_hours

检索所有订单的最佳且更有效的方法是worked_hours(记住订单 - > ConstructionSite-> WorkingHours)至少是installation_planned_in_hours的80%?

编辑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');
  }
}

那么如何有效地检查与特定订单关联的ConstructionSite的worked_hours是否高于或低于订单的installation_planned_in_hours的80%?

更确切地说,我的数据库中有更多条目(更多订单,建筑工地和工作时间)。我怎么能这样做:

$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 :(得分:0)

您可以使用:

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();