问题描述
我正在尝试将关联的计数结果添加到 where 条件中,例如:
$findQuery = $this->Products->find('all');
$findQuery->leftJoinWith('Synonyms',function($q) {
return $q->where(['Synonyms.title LIKE' => '%TEST%']);
});
$findQuery->select([
'amount_of_matching_synonyms' => $findQuery->func()->count('Synonyms.id')
]);
$findQuery->where([
'OR' => [
'Products.description LIKE' => '%TEST%','amount_of_matching_synonyms >' => 0
]
]);
现在发生的是,我得到了 1 个结果,其中包含 'amount_of_matching_synonyms' 字段。但这似乎有它应该返回的所有记录的累积结果。
请帮帮我!
解决方法
您应该首先弄清楚如何在纯 SQL 中执行这些操作,然后将内容转换到查询构建器中会容易得多。
计算相关数据需要加入相关数据并创建可以使用聚合函数的组,而您错过了后者。此外,您不能在 WHERE
子句中使用聚合,因为在应用 WHERE
子句之后进行分组,因此您必须改用 HAVING
子句。
用于过滤此类计数的基本 SQL 如下所示:
SELECT
COUNT(synonyms.id) amount_of_matching_synonyms
FROM
products
LEFT JOIN
synonyms ON synonyms.id = synonyms.product_id
GROUP BY
products.id
HAVING
amount_of_matching_synonyms > 0
将其转换为查询构建器将相当简单,您只需要 group()
和 having()
,如下所示:
$findQuery = $this->Products
->find()
->select([
'Products.description','amount_of_matching_synonyms' => $findQuery->func()->count('Synonyms.id')
])
->leftJoinWith('Synonyms',function(\Cake\ORM\Query $q) {
return $q->where(['Synonyms.title LIKE' => '%TEST%']);
})
->group('Products.id')
->having([
'OR' => [
'Products.description LIKE' => '%TEST%','amount_of_matching_synonyms >' => 0
],]);
注意一定要选择描述,否则have子句中的条件会失败。
生成的 SQL 看起来像这样:
SELECT
products.description,COUNT(synonyms.id) amount_of_matching_synonyms
FROM
products
LEFT JOIN
synonyms ON
synonyms.product_id = products.id
AND
synonyms.title LIKE '%TEST%'
GROUP BY
products.id
HAVING
products.description LIKE '%TEST%'
OR
amount_of_matching_synonyms > 0
另见