
本文讲解在 Laravel 中如何通过原生查询(raw query)高效统计 partner 表中 type 字段(如 'Yearly'、'Monthly'、'Weekly')的出现频次,并对比推荐的 Eloquent 方式与原生写法的优劣。
本文讲解在 laravel 中如何通过原生查询(raw query)高效统计 `partner` 表中 `type` 字段(如 'yearly'、'monthly'、'weekly')的出现频次,并对比推荐的 eloquent 方式与原生写法的优劣。
在实际开发中,常需对某字段的枚举值进行分组计数(例如统计合作伙伴类型分布)。虽然 Laravel 提供了简洁的 Eloquent 方法,但有时因复杂条件或性能优化需要,开发者会倾向使用原生 SQL 查询。下面我们将围绕 partner 表的 type 字段(存储 'Yearly'、'Monthly'、'Weekly' 等字符串值),提供清晰、安全、可维护的实现方案。
✅ 推荐方式:使用 Eloquent + groupBy()(高效且安全)
最符合 Laravel 最佳实践的方式是避免循环多次查询,改用单次聚合查询:
$counts = Partner::select('type', \DB::raw('count(*) as count'))
->whereIn('type', ['Yearly', 'Monthly', 'Weekly'])
->groupBy('type')
->get()
->pluck('count', 'type')
->toArray();
// 输出示例:['Yearly' => 142, 'Monthly' => 89, 'Weekly' => 37]
该方式仅执行 1 次数据库查询,利用 SQL 的 GROUP BY 高效完成统计,同时自动处理空类型过滤,代码简洁且防 SQL 注入。
⚠️ 原生查询方式(仅作技术参考,不推荐用于生产)
若明确需使用 DB::select() 执行原生 SQL(例如对接遗留逻辑或特殊数据库方言),请务必避免字符串拼接——否则将导致严重 SQL 注入漏洞。正确写法应使用参数绑定:
use Illuminate\Support\Facades\DB;
$typeList = ['Yearly', 'Monthly', 'Weekly'];
$partnerCounts = [];
foreach ($typeList as $type) {
$result = DB::select(
'SELECT COUNT(*) AS count FROM partner WHERE type = ?',
[$type]
);
$partnerCounts[$type] = $result[0]->count ?? 0;
}
❗ 错误示范(危险!禁止使用):
// 危险:直接拼接变量 → SQL 注入高危 DB::raw("SELECT COUNT(*) FROM partner WHERE type = '" . $type . "'");
? 调试技巧:查看真实执行的 SQL
在开发阶段,可通过以下方式确认生成的 SQL 是否符合预期:
DB::enableQueryLog(); // 启用日志 // 执行你的查询(例如上面的 select 或 Eloquent 调用) dd(DB::getQueryLog()); // 查看完整 SQL、绑定参数及执行耗时
? 注意事项总结
- 安全性优先:所有用户可控输入(包括 $type 值)必须通过参数绑定传递,禁用字符串拼接;
- 性能考量:N 次循环查询(N=3 类型)会产生 N 次数据库往返,而 GROUP BY 方案只需 1 次,I/O 开销显著更低;
- 健壮性增强:建议在 type 字段上添加数据库索引(INDEX(type)),大幅提升 WHERE 和 GROUP BY 效率;
- 扩展性提醒:若类型未来可能动态变化,可先 SELECT DISTINCT type FROM partner 获取全部有效值,再统一计数。
综上,除非有强约束要求必须用原生 SQL,否则应首选 Eloquent 的 groupBy() 方案——它更安全、更高效、更易测试与维护。











