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

Mysql 使用Laravel Eloquent获取嵌套实体的计数,mysql,eloquent,laravel-5.1,Mysql,Eloquent,Laravel 5.1,我有3个数据库表客户端,优惠券和类别 clients table 身份证, 名称 网站 描述 标志 鼻涕虫 身份证, 名称 鼻涕虫 身份证, 客户id, 类别识别码, 类型 息票 标题 描述 链接 意见, 鼻涕虫 到期日 关系是 1) 多张优惠券属于客户(多对一关系) 2) 多张优惠券属于类别(多对一关系) 我使用的是Laravel5.1 我如何通过客户详细信息、客户拥有的优惠券数量以及单个客户拥有的总类别数量获取客户的唯一数量 简化:我需要获得客户详细信息,并显示特定客户的xxx数量类别中有

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

clients table
身份证, 名称 网站 描述 标志 鼻涕虫

身份证, 名称 鼻涕虫

身份证, 客户id, 类别识别码, 类型 息票 标题 描述 链接 意见, 鼻涕虫 到期日

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

我使用的是Laravel5.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')]);
}
每_请求存储_=9(常数)进行分页。
提前感谢。

如果你已经建立了人际关系,你可以做如下事情:

 /**
 * 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;
}
public function scopeActive($query)
{
    $query->where('expiry', '>', Carbon::today());
}
上述内容可以在
客户机
模型中使用,然后您可以更改
类别
模型的
couponCount
关系方法(如果需要)

然后为您的
类别
计数添加以下内容:

 /**
 * 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;
}
然后,您可以在
优惠券
模型中添加查询范围,以获取未过期的优惠券,例如:

 /**
 * 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;
}
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()}]) ...

希望这有帮助

好吧,我用额外的信息计算出了自己的优惠券类型和可用类别。 我所做的关键是在count中添加case,并删除categories表的连接

最后的代码是这样的

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"
}]

这就成功了:)

谢谢。。我花了一整天的时间寻找解决办法,终于明白了。