获取关联表中列的总和

时间:2018-04-27 17:00:45

标签: cakephp-3.x

SETUP

我有以下数据库设置:

// Contacts
,----,--------,---------,----------,
| id | name   | surname | is_agent |
|----|--------|---------|----------|
| 1  | Jhon   | Doe     | Yes      |
'----'--------'---------'----------'

// ContactAttributes
,----,------------------,
| id | own_transport    |
|----|------------------|
| 1  | Yes              |
'----'------------------'

// Reviews
,----,------------,-------------,--------,
| id | contact_id | reviewed_by | rating |
|----|------------|-------------|--------|
| 1  | 1          | 7           | 5      |
| 2  | 1          | 5           | 3      |
| 3  | 1          | 4           | 4      |
'----'------------'-------------'--------'

联系人具有一对一的关系ContactAttributes和一对多的评论。审核者也会链接回“联系人”,但只能获取姓名和姓氏。

我想要什么

我想获得联系人的评分总和。因此,如果我提取联系人1,我希望将review_total视为12。

我做了什么

From the docs我可以看到我需要像这样建立我的查询:

$query = $contactsTable->find();
$query->select(['review_sum' => $query->func()->sum('Reviews.rating')])
    ->where([
        'Contacts.is_agent' => 'no',
        'ContactAttributes.own_transport' => 'Yes',
    ])
    ->contain(['ContactAttributes', 'Reviews'])
    ->first();

问题

我在运行上述内容时遇到此错误:

Error: SQLSTATE[42P01]: Undefined table: 7 ERROR: missing FROM-clause entry for table "reviews" LINE 1: SELECT (SUM(Reviews.rating)) AS "review_sum" FROM contacts C... ^

这是它试图运行的查询:

SELECT (SUM(Reviews.rating)) AS "review_sum" FROM contacts Contacts LEFT JOIN contact_attributes ContactAttributes ON Contacts.id = (ContactAttributes.id) WHERE (Contacts.is_agent = :c0 AND ContactAttributes.own_transport = :c1) LIMIT 1

问题

我该如何解决这个问题?我做错了什么或有更简单的方法吗?

编辑1

我让它像这样工作,但必须有更多的CakePHP方式。

$contactsTable->find()
    ->select([
        'Contacts.id',
        'Contacts.firstname',
        'Users.username',
        'Contacts.lastname',
        'Contacts.id_number',
        'Contacts.coordinates',
        'review_sum' => 'SUM(reviews.rating)'
    ])
    ->leftJoin(['Reviews' => 'reviews'], 'Reviews.contact_id = Contacts.id')
    ->leftJoin(['Users' => 'users'], 'Users.id = Contacts.id')
    ->leftJoin(['ContactAttributes' => 'contact_attributes'], 'ContactAttributes.id = Contacts.id')
    ->where([
        'Contacts.is_agent' => 'no',
        'ContactAttributes.own_transport' => $job->own_transport
    ])
    ->orderDesc('review_sum')
    ->group('Users.username')
    ->group('Contacts.id')
    ->having(['SUM(Reviews.rating) IS NOT NULL']);

3 个答案:

答案 0 :(得分:2)

由于您拥有belongsToMany关系,因此您必须将该函数放入Contain调用

Submission

答案 1 :(得分:0)

我认为您的查询缺少JOIN。您有联系人和ContactAttributes但没有评论。你需要添加这样的东西。

bank_data.update({k: year_converter(v) for k, v in bank_data.items()})

答案 2 :(得分:0)

看起来在您执行总和时,$ query仅使用一个表进行了部分初始化。尝试用这个替换第一行。

$query = $contactsTable->find()->contain(['ContactAttributes', 'Reviews']);

并删除末尾的包含行。