Laravel查询异常排查:如何正确组合Like模糊查询与日期范围条件?
解决Laravel查询中OR与AND条件的逻辑优先级问题
这是个典型的SQL逻辑运算符优先级坑,我来帮你快速搞定它!
问题根源
你当前的查询语句因为运算符优先级的问题,实际执行的逻辑和你预期的完全不一样。SQL里AND的优先级比OR高,所以你的原始代码生成的SQL等价于:
SELECT page as value, COUNT(ID) as `count` FROM clientpages WHERE page LIKE '%blog%' OR (page LIKE '%home%' AND date BETWEEN '你的起始日期' AND '你的结束日期')
这就导致:要么是包含blog的记录(不管日期是否在范围内),要么是包含home且日期在范围内的记录。如果你的home数据刚好不在指定日期范围内,自然就只返回blog的结果了——这和你描述的现象完全吻合。
正确的写法
你需要把两个LIKE条件分组,让它们先做OR判断,再和日期范围的AND条件结合。在Laravel里,用闭包就能轻松实现这个分组:
clientpages::selectRaw('page as value, COUNT(ID) as `count`') ->whereBetween('date', [$range['from'], $range['to']]) ->where(function ($query) { // 闭包里的条件会被自动加上括号,形成独立的逻辑组 $query->where('page', 'like', '%blog%') ->orWhere('page', 'like', '%home%'); }) ->groupBy('page'); // 必须加上分组,否则聚合函数COUNT的结果会不符合预期
这段代码生成的SQL是符合你预期的:
SELECT page as value, COUNT(ID) as `count` FROM clientpages WHERE date BETWEEN '你的起始日期' AND '你的结束日期' AND (page LIKE '%blog%' OR page LIKE '%home%') GROUP BY page
逻辑变成了:先筛选日期在范围内的记录,再从中找出包含blog或home的页面,最后按页面分组统计数量。
额外提醒
别忘了加上groupBy('page'),因为你用了聚合函数COUNT(ID)。如果没有分组,在开启SQL严格模式的环境下会直接报错,而且统计出来的结果也不是按每个页面分别计数的。
内容的提问来源于stack exchange,提问作者Gimmly
相关产品推荐
相关产品推荐

