CakePHP 4:如何将关联结果的计数添加到where条件

isr3a4wc  于 2022-11-12  发布在  PHP
关注(0)|答案(1)|浏览(229)

我尝试将关联的计数结果添加到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
    ]
]);

现在发生的情况是,我得到了一个带有'amount_of_matching_synonyms'字段的返回结果,但这似乎是它应该返回的所有记录的累积结果。
请帮帮我!

ufj5ltwl

ufj5ltwl1#

您应该首先弄清楚如何在纯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
        ],
    ]);

请注意,您需要选择描述,否则having子句中的条件将失败。
生成的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

另请参阅


*Cookbook〉数据库访问和ORM〉查询生成器〉聚合-分组和拥有
*操作手册〉数据库访问和ORM〉查询生成器〉子查询

相关问题