如何在Laravel 5.4中实现指定SQL查询?
问题分析
嘿,我来帮你搞定这个Laravel查询的问题!先理清楚问题出在哪:
你最初的目标是找出所有fecha字段重复出现(记录数>1)的noticias表记录,对应的原生SQL逻辑是对的,但你写的Laravel查询构造器代码有两个关键错误:
- 逻辑偏差:
having('fecha', '>', 1)是在判断fecha字段的数值大于1,而不是判断该日期的记录数量大于1,完全偏离了你的需求; - 语法违规:在MySQL默认开启的严格模式(包含
ONLY_FULL_GROUP_BY规则)下,使用GROUP BY时,SELECT语句里的非聚合列(比如id、titulo这类字段)必须全部出现在GROUP BY子句中,否则就会抛出1055错误——你的代码用groupBy('fecha')却要select *,自然触发了这个规则。
正确的实现方法
下面给你两种和原生SQL逻辑完全匹配的Laravel写法,都能解决问题:
方法一:子查询匹配(最贴近你的原生SQL)
直接把你写的原生SQL翻译成Laravel查询构造器的写法,通过whereIn嵌套子查询获取重复的日期,再筛选原表记录:
$duplicateNoticias = DB::table('noticias') ->whereIn('fecha', function ($subquery) { $subquery->select('fecha') ->from('noticias') ->groupBy('fecha') ->havingRaw('count(*) > 1'); // 用havingRaw直接写聚合判断逻辑 }) ->get();
方法二:关联子查询(大数据量下性能更优)
先把重复的日期生成一个临时结果集,再和原表做关联查询,适合数据量较大的场景:
$duplicateNoticias = DB::table('noticias as n') ->join( // 生成包含重复日期的临时表 DB::raw('(SELECT fecha FROM noticias GROUP BY fecha HAVING COUNT(*) > 1) AS dup_fechas'), 'n.fecha', '=', 'dup_fechas.fecha' ) ->select('n.*') // 指定只取原表的所有字段 ->get();
额外提醒
别为了绕过1055错误就关闭MySQL的ONLY_FULL_GROUP_BY模式——这是SQL标准的要求,关闭后可能会返回不可预测的查询结果,得不偿失。
内容的提问来源于stack exchange,提问作者nature
相关产品推荐
相关产品推荐

