首页 > 解决方案 > CakePHP 4:如何将关联结果计数添加到 where 条件

问题描述

我正在尝试将关联的计数结果添加到 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”字段返回的结果。但这似乎是它应该返回的所有记录的累积结果。

请帮帮我!

标签: mysqlcakephpcountquery-buildercakephp-4.x

解决方案


你应该首先弄清楚如何用普通的 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()and 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

也可以看看


推荐阅读