Laravel中如何使用raw等方法简单执行复杂SQL查询统计邮件数据
Laravel执行该统计查询的两种实现方案
方案1:直接执行原生SQL(适配你已调试好的原有SQL,改动最小)
直接使用DB::select方法执行原生语句,同时使用参数绑定避免SQL注入风险:
use Illuminate\Support\Facades\DB; $mes = 8; $search = [100, 101, 102, 103]; // 构造IN占位符,做参数绑定处理 $inPlaceholders = implode(',', array_fill(0, count($search), '?')); $results = DB::select(" SELECT A.dni, ? AS mes, COUNT(*) AS total, B.lastet_date FROM emails AS A LEFT JOIN ( SELECT dni, MAX(date_sended) AS lastet_date FROM emails GROUP BY dni ) AS B ON B.dni = A.dni WHERE MONTH(date_sended) = ? AND A.dni IN ({$inPlaceholders}) GROUP BY A.dni ", array_merge([$mes, $mes], $search));
执行后返回的$results就是包含dni、对应月份、发送总量、最后发送时间的结果集合。
方案2:使用查询构造器+Raw方法(更符合Laravel编码规范,便于后续维护)
用Laravel自带的查询构造器实现逻辑,自动处理参数绑定,可读性更强:
use Illuminate\Support\Facades\DB; $mes = 8; $search = [100, 101, 102, 103]; $results = DB::table('emails as A') ->selectRaw('A.dni, ? as mes, COUNT(*) as total, B.lastet_date', [$mes]) ->leftJoinSub(function ($query) { $query->from('emails') ->select('dni', DB::raw('MAX(date_sended) as lastet_date')) ->groupBy('dni'); }, 'B', 'B.dni', '=', 'A.dni') ->whereRaw('MONTH(date_sended) = ?', [$mes]) ->whereIn('A.dni', $search) ->groupBy('A.dni') ->get();
如果你的Laravel版本低于5.6不支持leftJoinSub方法,可以替换为join+Raw写法实现子查询逻辑,效果完全一致。
内容的提问来源于stack exchange,提问作者Mauricio
相关产品推荐
相关产品推荐

