繁体   English   中英

计数子表中的相关行

[英]Counting related rows in a child table

我一直在尝试进行一些查询,并雄辩地使用相关表进行计数。

表格:

  • 要求
  • 联系人(属于请求)
  • 历史(属于联系方式)

这样,X个请求中的每个都有Y个联系人,因此每个联系人都有Z个历史记录

使用sql,我可以做这样的事情来获取所有计数。

SELECT
    id,
    (
         SELECT count(contact.id)
         FROM contact 
         WHERE contact.requests_id = requests.id
    ) AS n_contact,
    (
         SELECT count(history.id)
         FROM contact INNER JOIN history ON (history.contact_id = contact.id)
         WHERE contact.requests_id = requests.id
    ) AS n_history
FROM requests;

以上查询

但是当我用雄辩的方式建立查询时,我有点迷失了。 例如,如果我要为给定请求选择所有联系人,我将在什么时候加入/计算历史记录? 还是我需要在这3个表的相关模型中添加一些访问器?

public function getAllContacts($id) {
    return Requests::where('requests.id', '=', $id)
            ->join('requests', 'contact.requests_id', '=', 'requests.id')
            ->select('contact.*', 'requests.name');
            ->get();
}

在此先感谢您的帮助。

如果您想使用Eloquent而不是手动联接,则可以使用辅助关系:

// Request model
public function contactsCount()
{
    return $this->hasOne('Contact')->selectRaw('request_id, count(*) as aggregate')->groupBy('request_id');
}

public function getContactsCountAttribute()
{
    if ( ! array_key_exists('contactsCount', $this->relations)) $this->load('contactsCount');

    return $this->getRelation('contactsCount')->aggregate;
}

对于“ History模型,“ Contact History模型也是如此。

对于计数远的关系( Request - > History ),可以使用hasManyThrough关系一点点调整。

这样,您就可以渴望为多个模型加载这些聚合,而不会出现n + 1问题,既简单又方便:

$requests = Request::with('contactsCount', 'contacts.historyCount')->get();
// 1 query for reuqests, 1 query for contacts count and 2 queries for contacts.historyCount

// example output
$requests->first()->contactsCount; // 17
$requests->first()->contacts->first()->historyCount; // 5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM