You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不修改sql_mode=only_full_group_by时如何在CakePHP中正常执行group by查询

错误原因

开启sql_mode=only_full_group_by后,MySQL要求ORDER BY子句中的字段要么属于GROUP BY的字段列表,要么是经过聚合函数计算的结果。你当前代码GROUP BY的是月份名称month,但ORDER BY直接使用了未聚合的原始字段Transactions.created,不符合该规则,所以触发报错。
另外你的原有代码还存在潜在逻辑问题:如果统计周期跨年,monthname会把不同年份的相同月份数据合并,导致统计结果错误。

修复方案

推荐使用更严谨的写法,新增年、月数值字段用于分组和排序,同时解决报错和潜在的跨年统计错误:

public function getLastSixMOnthsExpenses($since_date, $t_type)
{
    $query = $this->find()->select([
            'year' => $this->find()->func()->year([
                'created' => 'identifier'
            ]),
            'month_num' => $this->find()->func()->month([
                'created' => 'identifier'
            ]),
            'month' => $this->find()->func()->monthname([
                'created' => 'identifier'
            ]),
            'amount' => $this->find()->func()->sum('Transactions.amount')
        ])
        ->where([
            'Transactions.created >='=>  $since_date->modify('6 months ago')->startOfMonth(),
            'Transactions.created <='=>  $since_date->endOfMonth(),
            'Transactions.transaction_type '=>$t_type
        ])
        // 按年+月分组,避免跨年数据合并
        ->group(['year', 'month_num', 'month'])
        // 用分组内的年、月字段排序,符合only_full_group_by规则
        ->order(['year' => 'ASC', 'month_num' => 'ASC'])
    ;

    return $query;
}

如果不需要保留年字段,也可以用简化方案,直接对created用聚合函数包裹后排序:

// 仅修改order子句即可
->order(['MIN(Transactions.created)' => 'ASC'])

两种方案都不需要修改sql_mode配置即可正常运行。

内容的提问来源于stack exchange,提问作者Niloy Rony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:12:01