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

Laravel开启database.php strict=true时,如何修改查询语句实现未完全分配交易的查询需求?

解决Laravel严格模式下关联查询的GROUP BY问题

遇到这个问题很常见——开启strict模式后,MySQL的only_full_group_by规则会严格校验GROUP BY子句和SELECT字段的对应关系,原查询里的whereHas子查询默认用select *,包含了transaction_allocations.id等不在GROUP BY中的非聚合字段,所以触发了1055错误。

不用关闭严格模式,我们可以通过修改查询语句来适配规则,下面给你两种可行的方案:

方案一:修正whereHas子查询的字段选择

原查询的问题出在whereHas的子查询里,我们只需要明确选择分组字段,并调整HAVING子句的逻辑即可:

Transaction::where('contact_id', 9)
    ->with('allocations')
    ->whereHas("allocations", function ($query) {
        // 只选择分组需要的transaction_id,避免select *带来的字段不匹配问题
        $query->select('transaction_id')
            ->havingRaw('(SELECT credit FROM transactions WHERE id = transaction_id) > sum(amount)')
            ->groupBy('transaction_id');
    })
    ->orDoesntHave("allocations")
    ->get();

为什么这样改?

  • 子查询现在只返回transaction_id,和GROUP BY的字段完全一致,符合only_full_group_by的要求
  • HAVING子句通过嵌套查询获取对应交易的credit值,保持了原有的比较逻辑

方案二:改用LEFT JOIN + GROUP BY(更高效简洁)

如果想简化查询逻辑,用LEFT JOIN一次性处理“有分配但未完全分配”和“无分配”两种情况,性能也会更好:

Transaction::where('contact_id', 9)
    ->with('allocations')
    ->leftJoin('transaction_allocations', 'transactions.id', '=', 'transaction_allocations.transaction_id')
    // 严格模式下,SELECT中的非聚合字段必须出现在GROUP BY里
    ->groupBy('transactions.id', 'transactions.credit')
    ->havingRaw('COALESCE(SUM(transaction_allocations.amount), 0) < transactions.credit OR COUNT(transaction_allocations.id) = 0')
    ->get();

逻辑说明:

  • LEFT JOIN会保留所有交易记录,包括没有分配的
  • COALESCE(SUM(...), 0)处理无分配记录的情况(此时SUM结果为null,转成0)
  • COUNT(transaction_allocations.id) = 0直接匹配没有关联分配的交易
  • GROUP BY包含transactions.id和transactions.credit,因为我们在SELECT和HAVING里用到了这两个非聚合字段,符合严格模式要求

原查询报错的核心原因

当你使用whereHas时,Laravel默认生成的子查询是select * from transaction_allocations ... group by transaction_id,但SELECT列表里的id、bill_id等字段既不在GROUP BY里,也没有用聚合函数包裹,违反了only_full_group_by的规则——严格模式下,MySQL要求所有非聚合的SELECT字段必须是GROUP BY的一部分,或者函数依赖于GROUP BY字段(比如主键)。

内容的提问来源于stack exchange,提问作者Lucid Polygon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:33:11