首页 > 解决方案 > Eloquent:子关系查询中的 withCount 和 OrderBy

问题描述

我实际上有这个结构:

我想要实现的是让所有零售商按可以在那里使用的每张优惠券的 face_values 的总量 (SUM) 订购。

我尝试了不同的方法,但我无法正确获得结果。

最接近的结果是通过这种方式创建多个 leftJoin:

$retailerList = Retailer::withCount(['geoCampaign as totalReduc' => function($query) use($today){
                        $query->leftJoin('campaigns', 'campaigns.uuid', 'geo_restricted_campaigns.campaign_id')
                                ->leftJoin('coupons', 'coupons.uuid', 'campaigns.coupon_id')
                                ->select(DB::raw("SUM(facial_value) as facialValue"))
                                ->where('campaigns.status', '=', 1)
                                ->bunch of other where clauses
                                ;
                    }])
                    ->orderBy('totalReduc', 'DESC')
                    ->limit(15)
                    ->get()
                    ;

通过这种方式,我可以正确计算 face_values(totalReduc SUM),但似乎我的所有位置都没有“使用”,并且无论我尝试在哪里限制,它都会返回附加到零售商的所有活动添加。此外,我不太喜欢像这样进行连接,我应该能够以更雄辩的方式进行连接。

我还尝试了另一种方法,以这种方式在我的零售商模型上添加 geoActiveCampaign 关系

class Retailer extends Model 
{
 public function geoCampaign()
    {
        return $this->hasMany(GeoRestrictedCampaign::class, 'retailer_id');
    }

    public function geoActiveCampaign()
    {
        return $this->geoCampaign()->whereHas('activeCampaign');
    }
}

class GeoRestrictedCampaign extends Model 
{
public function activeCampaign()
    {
        return $this->campaign()->where('status', '=', 1)
                                -> all my other where clauses
                                ;
    }
}

但是在这里我无法计算 face_values(我无法与优惠券建立关系,因为我认为我没有从查询中返回正确的模型)。

我觉得我在这里兜圈子。

感谢任何帮助我指出正确方向的帮助。谢谢你。

编辑:回到我的多 leftJoin 版本后,我意识到我没有正确传递 where 子句(我需要将它们作为闭包传递),如下所示:

    $retailerList = Retailer::withCount(['geoCampaign as totalReduc' => function($query) use($today){
                            $query->leftJoin('campaigns', function($query) use($today){
                                $query->on('campaigns.uuid', 'geo_restricted_campaigns.campaign_id')
                                        ->where('campaigns.status', '=', 1)
                                        ->bunch of other where clauses
                                    ;
                            })
                            ->leftJoin('coupons', 'coupons.uuid', 'campaigns.coupon_id')
->select(DB::raw("SUM(facial_value) as facialValue"))
                            ;
                        }])
                        ->orderBy('totalReduc', 'DESC')
                        ->limit(15)
                        ->get()
                        ;

但我仍然对它不太满意(感觉不是正确的做法)。

第二次编辑:经过更多挖掘后,多重连接似乎是实现这一目标的唯一方法。

标签: eloquenteloquent-relationship

解决方案


推荐阅读