首页 > 解决方案 > 使用 Eloquent 获取连接表的最小值

问题描述

我有 2 张桌子,subscriptions就像subscription_options这样。

subscriptions
------------------------
id    |subscription_name
------------------------
1     |silver
2     |gold


----------------------------------------------------
subscription_options
----------------------------------------------------
id    |subscription_id   |price   |duration (months)
1     |1                 |10      |3
2     |1                 |20      |6
3     |2                 |40      |3
4     |2                 |50      |6

subscriptions有一对多的关系subscription_options

// Subscription model
public function options() {

    return $this->hasMany('App\SubscriptionOption', 'subscription_id');
}

我想为我的两个订阅获得最便宜的价格,所以我应该得到 2 行subscription_optionsid的所有列13我将如何用 laravel eloquent 做到这一点?

这些是我尝试过的东西,它们要么给了我一个错误,要么返回了一些接近我正在寻找的东西

Subscription::with('options')->min('price')->get();


Subscription::with(['options' => function($query) {
         $query->min('price');
     }])->get();

标签: laraveleloquentorm

解决方案


有很多方法可以做到这一点,这是程序员偏好的问题......

其中之一是创建一个仅获得最便宜价格的子查询,然后使用 subQuery join加入该子查询

$subQuerysubscription_options=Subscription_option::
selectRaw("id as cheapest_option_id,min(price) as cheapest_price")->groupBy('id');




      $subscription = Subscription::
join('subscription_options','subscription_options.subscription_id','subscriptions.id')->
            joinSub($subQuerysubscription_options, 'subQuerysubscription_options', function ($join) {
                $join->on('subscription_options.id', '=', 'subQuerysubscription_options.cheapest_option_id');
            })
            ->
            select('subscriptions.*','subscription_options.*')

        ->get();

由于我们使用的是“join”而不是“leftJoin”,因此查询将保证只有与 subQuery 中的行匹配的行才会得到结果

选项2:

$minCheapestIds=Subscription_option::
selectRaw("id as cheapest_option_id,min(price) as cheapest_price")->groupBy('id')->pluck('cheapest_option_id');

现在我们有一个最便宜的订阅选项ID列表......

  $values=  Subscription::with(['options' => function($query) use($minCheapestIds){
             $query->whereIn('subscription_options.id',$minCheapestIds);
         }])->get();

这意味着在最便宜的地方加载 Subscription 的选项..


推荐阅读