使用HAVING子句中的聚合函数构建查询

问题描述 投票:0回答:1

[我正在尝试使用CakePHP的查询生成器来确定在hading子句中如何具有聚合函数。

背景:目的是使用复合主键(页面ID和URL)更正表中的所有行,以使每个页面ID组只有一个默认视频。有一些组没有,有些组有一个以上的“默认”行,需要更正。我已经弄清楚了所有步骤–除了这个细节。

这是我要构建的查询。

SELECT 
        video_page_id, video_url
    FROM page_video 
    WHERE 
        video_page_id IN (
            SELECT video_page_id 
                FROM page_video 
                GROUP BY video_page_id 
                HAVING SUM(video_is_default) < 1
        ) 
    AND video_order = 0 
    ;

这就是我建造的:

    // sub-select: all groups that have too few defaults.
    // Returns list of page-IDs.
    $qb = $this->getQueryBuilder();
    $group_selection = $qb
        ->select(array(
            'video_page_id',
        ))
        ->from('page_video')
        ->group('video_page_id')
        ->having(array(
            '1 >' => $qb->func()->sum('video_is_default'),
        ))
    ;

    // sub-select: compound-primary-key identifiers of all rows where
    // `video_is_default` has to be modified from `0` to `1`.
    // Returns list of two columns.
    $qb = $this->getQueryBuilder();
    $modifiable_selection = $qb
        ->select(array(
            'video_page_id',
            'video_url',
        ))
        ->from('page_video')
        ->where(array(
            'video_page_id IN' => $group_selection,
            'video_order = 0',
        ))
    ;

但是后来我得到了这个例外:Column not found: 1054 Unknown column '1' in 'having clause'

关键是HAVING子句。我基本上不知道如何将聚合函数与数组的属性值属性组合在一起。通常,为了编写低于/大于的子句,您应这样编写:array('col1 >' => $value)。但是在这里,我需要翻转方程式,因为复杂的表达式无法放入数组键中。现在1被解释为列名。


将其写为连接字符串似乎也无济于事。

array(
    $qb->func()->sum('video_is_default') .' > 1',
)

例外:PHP Recoverable fatal error: Object of class Cake\Database\Expression\FunctionExpression could not be converted to string


我知道我可以做……

SELECT (…), SUM(video_is_default) AS default_sum FROM (…) HAVING default_sum < 1 (…)

…但是子选择列数不再匹配。

例外:ERROR 1241 (21000): Operand should contain 1 column(s)

aggregate-functions cakephp-3.x having
1个回答
0
投票

问了问题后这么快就找出解决方案,我感到很傻。

lt方法接受复数值作为第一个参数。

->having(function($exp, $qb) {
    $default_sum = $qb->func()->sum('video_is_default');
    return $exp->lt($default_sum, 1);
})
© www.soinside.com 2019 - 2024. All rights reserved.