Laravel Eloquent关联查询where('contact_id',$id)条件被忽略原因排查
问题原因
- 这是SQL逻辑运算符优先级导致的条件失效。你写的查询生成的原生SQL条件结构为:
SQL中WHERE contact_id = ? AND whereHas匹配条件 OR doesNotHave匹配条件AND的优先级高于OR,所以实际执行时的判断逻辑是:(contact_id = ? AND whereHas匹配) OR (doesNotHave匹配),OR后面的条件没有绑定contact_id限制,自然会返回不属于对应contact的记录。 - 你写的
havingRaw里直接引用主表transactions.amount是合法的,whereHas的子查询可以直接读取主表字段,这部分逻辑没有问题。
修复方案
只需要把whereHas和orDoesntHave这两个互斥的业务条件放到同一个闭包where中,强制让它们作为一个整体和contact_id条件做AND判断即可,修复后的代码如下:
Transaction::where('contact_id', $id) ->with('allocations') ->where(function ($query) { $query->whereHas("allocations", function ($subQuery) { $subQuery->select('transaction_id') ->havingRaw('transactions.amount > sum(amount)') ->groupBy('transaction_id'); }) ->orDoesntHave("allocations"); }) ->get();
调整后生成的SQL条件结构为:
WHERE contact_id = ? AND (whereHas匹配条件 OR doesNotHave匹配条件)
完全匹配业务需求:指定contact下的交易记录,要么没有关联allocations记录,要么自身amount大于所有关联allocations的amount总和。
内容的提问来源于stack exchange,提问作者Lucid Polygon
相关产品推荐
相关产品推荐

