
本文介绍在 Laravel 中通过原生查询或 Eloquent 方式高效统计表中某字段(如 type)各枚举值的出现频次,涵盖安全写法、性能对比及调试技巧。
本文介绍在 laravel 中通过原生查询或 eloquent 方式高效统计表中某字段(如 `type`)各枚举值的出现频次,涵盖安全写法、性能对比及调试技巧。
在实际开发中,我们常需对分类字段(如 partner.type)进行分组计数,例如统计 Yearly、Monthly、Weekly 三类合作伙伴的数量。虽然可逐个 where() 查询,但更推荐单次聚合查询以提升性能与可维护性。
✅ 推荐方式:使用 Eloquent 的 groupBy + count()
// 一行代码获取完整统计结果(返回集合)
$counts = Partner::select('type', \DB::raw('count(*) as count'))
->groupBy('type')
->get()
->pluck('count', 'type'); // 转为 ['Yearly' => 123, 'Monthly' => 45, 'Weekly' => 67]
// 输出示例
dd($counts->all()); // ['Yearly' => 89, 'Monthly' => 132, 'Weekly' => 41]
该方式生成标准 SQL:
SELECT `type`, COUNT(*) AS count FROM `partner` GROUP BY `type`;
简洁、安全、无需手动拼接字符串,且自动防止 SQL 注入。
⚠️ 不推荐的原生查询写法(仅作警示)
若坚持使用 DB::select() 手动拼接,必须避免直接插入变量:
❌ 危险示例(SQL 注入风险):
$value = "Yearly'; DROP TABLE partner; --";
DB::select("SELECT COUNT(*) FROM partner WHERE type = '$value'");
✅ 安全替代(使用参数绑定):
foreach ($type as $t) {
$result = DB::select(
'SELECT COUNT(*) as count FROM partner WHERE type = ?',
[$t]
);
$partner[] = $result[0]->count;
}
? 调试技巧:查看真实执行的 SQL
启用查询日志便于验证逻辑:
\DB::enableQueryLog();
$counts = Partner::select('type', \DB::raw('count(*)'))->groupBy('type')->get();
\dd(\DB::getQueryLog()); // 输出含绑定参数的完整 SQL
? 总结建议
- 优先使用 Eloquent 聚合查询(groupBy + count),语义清晰、性能优异、安全可靠;
- 避免循环多次查询同一张表——单次 GROUP BY 比 N 次 WHERE 查询快数倍;
- 若必须用原生 SQL,请始终使用参数绑定(? 占位符),杜绝字符串拼接;
- 利用 enableQueryLog() 快速定位低效或异常 SQL,尤其在迁移旧逻辑时。
最终,一个健壮、可读、高性能的统计方案应是:
$partnerCounts = Partner::query()
->select('type', \DB::raw('count(*) as total'))
->whereIn('type', ['Yearly', 'Monthly', 'Weekly'])
->groupBy('type')
->pluck('total', 'type');
它兼顾完整性、安全性与扩展性,是生产环境的最佳实践。











