获取关联 table 中列的总和
Get sum of column in associated table
设置
我有以下数据库设置:
// 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']);
我认为您的查询缺少 JOIN。您有 Contacts 和 ContactAttributes 但没有 Reviews。您需要添加类似这样的内容。
LEFT JOIN Reviews ON Contacts.id = Reviews.contact_id
看起来在您进行求和时,$query 仅使用一个 table 进行了部分初始化。尝试用这个替换第一行。
$query = $contactsTable->find()->contain(['ContactAttributes', 'Reviews']);
并删除末尾的包含行。
因为你有 belongsToMany 关系,你必须把函数放在 Contain 调用中
$query
->where([
'Contacts.is_agent' => 'no',
'ContactAttributes.own_transport' => 'Yes',
])
->contain([
'ContactAttributes',
'Reviews' => function($q) {
$q->select([
'review_sum' => $query->func()->sum('Reviews.rating')
])
->group(['contact_id'])
}])
->first();
设置
我有以下数据库设置:
// 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']);
我认为您的查询缺少 JOIN。您有 Contacts 和 ContactAttributes 但没有 Reviews。您需要添加类似这样的内容。
LEFT JOIN Reviews ON Contacts.id = Reviews.contact_id
看起来在您进行求和时,$query 仅使用一个 table 进行了部分初始化。尝试用这个替换第一行。
$query = $contactsTable->find()->contain(['ContactAttributes', 'Reviews']);
并删除末尾的包含行。
因为你有 belongsToMany 关系,你必须把函数放在 Contain 调用中
$query
->where([
'Contacts.is_agent' => 'no',
'ContactAttributes.own_transport' => 'Yes',
])
->contain([
'ContactAttributes',
'Reviews' => function($q) {
$q->select([
'review_sum' => $query->func()->sum('Reviews.rating')
])
->group(['contact_id'])
}])
->first();