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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:06:00