使用Laravel Eloquent获取嵌套实体的数量

时间:2015-09-07 03:03:32

标签: mysql eloquent laravel-5.1

我有3个数据库表客户端,优惠券和类别

clients table

ID, 名称, 网站, 描述, 商标, 蛞蝓

categories table

ID, 名称, 蛞蝓

coupons table

ID, CLIENT_ID, CATEGORY_ID, 类型, 优惠券, 标题, 描述, 链接, 意见, 蛞蝓, 期满

关系是 1)许多优惠券属于客户(多对一关系) 2)许多优惠券属于类别(多对一关系)

我正在使用laravel 5.1。

如何通过客户详细信息,客户拥有的优惠券数量以及单个客户的总类别数量来获取客户的唯一数量。

简化:我需要获取客户详细信息并显示特定客户的xxx类别中有xxx个优惠券数量。

到目前为止,我可以获得唯一的客户详细信息和优惠券数量。

 public function getAvailableClientsWithItemCountList($page = 1)
{
    return Client::join('coupons', 'clients.id', '=', 'coupons.client_id')
        ->join('categories', 'coupons.category_id', '=', 'categories.id')
        ->where('coupons.expiry', '>', Carbon::today())
        ->groupBy('clients.id')
        ->skip(STORES_PER_REQUEST*($page-1))
        ->take(STORES_PER_REQUEST)
        ->get(['clients.id', 'clients.name', 'clients.slug', 'clients.logo', DB::raw('count(clients.id) as dealsCount'), DB::raw('count(categories.id) as categoriesCount')]);
}

STORES_PER_REQUEST = 9(常数)用于分页。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

如果您建立了自己的关系,可以执行以下操作:

 /**
 * Mock relationship for eager loading coupon count
 *
 * @return mixed
 */
public function couponCount()
{
    return $this->hasOne(Coupon::class)
        ->selectRaw('client_id, count(*) as aggregate')
        ->groupBy('client_id');

}

public function getCouponCountAttribute()
{
    // if relation is not loaded already, let's do it first
    if (!$this->relationLoaded('couponCount')) {
        $this->load('couponCount');
    }

    $related = $this->getRelation('couponCount');

    // then return the count directly
    return ($related) ? (int) $related->aggregate : 0;
}

以上内容可以在您的Client模型中使用,然后您只需更改couponCount模型的Category关系方法(如果您愿意)。

然后为Category计数添加以下内容:

 /**
 * Mock relationship for eager loading category count
 *
 * @return mixed
 */
public function categoryCount()
{
    return $this->hasOne(Coupon::class)
        ->selectRaw('category_id, count(*) as aggregate')
        ->groupBy('client_id, category_id');

}

public function getCategoryCountAttribute()
{
    // if relation is not loaded already, let's do it first
    if (!$this->relationLoaded('categoryCount')) {
        $this->load('categoryCount');
    }

    $related = $this->getRelation('categoryCount');

    // then return the count directly
    return ($related) ? (int) $related->aggregate : 0;
}

然后,您可以在Coupon模型中添加查询范围,以获取未过期的优惠券:

public function scopeActive($query)
{
    $query->where('expiry', '>', Carbon::today());
}

如果你只是计算未过期的优惠券,你可以添加,你可以直接添加到关系中,例如 groupBy('client)id')->active()

现在你应该能够像这样急切地加载关系:

 $clients = Client::with('couponCount', 'clientCount')
    ->skip(STORES_PER_REQUEST * ($page - 1))
    ->take(STORES_PER_REQUEST)
    ->get();

或者您可以将查询范围附加到急切负载,即

 $clients = Client::with(['couponCount' => function ($q) {$q->active()}, 'clientCount' => function ($q) {$q->active()}]) ...

希望这有帮助!

答案 1 :(得分:0)

好吧我发现自己有额外的信息作为优惠券类型和可用的类别。 我所做的关键只是在计数中添加了案例并删除了类别表的连接。

最终代码看起来像这样

return App\Client::join('coupons', 'clients.id', '=', 'coupons.client_id')
    ->where('coupons.expiry', '>', \Carbon\Carbon::today())
    ->orderBy('clients.position', 'desc')
    ->groupBy('clients.id')
    ->skip(STORES_PER_REQUEST*(1-1))
    ->take(STORES_PER_REQUEST)
    ->get(['clients.id', 'clients.name', 'clients.slug', 'clients.logo', DB::raw('count(clients.id) as total'), DB::raw('count(CASE WHEN coupons.type=\'Coupon\' THEN 1 ELSE NULL END) as couponsCount'), DB::raw('count(CASE WHEN coupons.type=\'Deals\' THEN 1 ELSE NULL END) as dealsCount'), DB::raw('count(Distinct category_id) as categoriesCount')]);

结果是

[{
"id": "8",
"name": "Archies Online",
"slug": "archies-online",
"logo": "Archiesonline.jpg",
"total": "22",
"couponsCount": "20",
"dealsCount": "2",
"categoriesCount": "9"
}, {
"id": "5",
"name": "Shop Clues",
"slug": "shop-clues",
"logo": "Shopclues.jpg",
"total": "24",
"couponsCount": "24",
"dealsCount": "0",
"categoriesCount": "9"
}, {
"id": "6",
"name": "Lens Kart",
"slug": "lens-kart",
"logo": "Lenskart.jpg",
"total": "25",
"couponsCount": "25",
"dealsCount": "0",
"categoriesCount": "8"
}, {
"id": "7",
"name": "Amazer",
"slug": "amazer",
"logo": "Amzer.jpg",
"total": "21",
"couponsCount": "21",
"dealsCount": "0",
"categoriesCount": "8"
}, {
"id": "1",
"name": "Flipkart",
"slug": "flipkart",
"logo": "Flipkart.jpg",
"total": "17",
"couponsCount": "17",
"dealsCount": "0",
"categoriesCount": "9"
}, {
"id": "2",
"name": "Make My Trip",
"slug": "make-my-trip",
"logo": "Makemytrip.jpg",
"total": "11",
"couponsCount": "11",
"dealsCount": "0",
"categoriesCount": "8"
}]

这就是现在的诀窍:);