如何在Laravel Eloquent中无需selectRaw实现复杂MySQL年龄计算查询
要实现该年龄计算逻辑且不直接使用selectRaw,可以用DB::raw配合select方法拆分表达式,同时你原有SQL中的年龄计算逻辑可以直接用MySQL原生的TIMESTAMPDIFF函数简化,最终代码可读性更高,效果和原逻辑完全一致:
use Illuminate\Support\Facades\DB; Relation::select([ DB::raw('COUNT(relation.id) AS amount'), DB::raw('IF(relation.type != 2, TIMESTAMPDIFF(YEAR, IF(relation.birthday = 0, NULL, relation.birthday), NOW()), NULL) AS age') ]) ->where(function ($query) { $query->whereNull('relation.stopdate') ->orWhere('relation.stopdate', '>', now()); }) ->groupBy('age') ->orderBy('age') ->get();
如果你确实需要完全规避所有raw类方法(即不在SQL层面做计算),可以在查询出集合后用Laravel集合方法做分组统计,仅适合数据量较小的场景:
use Carbon\Carbon; $relations = Relation::where(function ($query) { $query->whereNull('relation.stopdate') ->orWhere('relation.stopdate', '>', now()); })->get(['id', 'type', 'birthday']); $ageStatistics = $relations->groupBy(function ($item) { if ($item->type == 2 || empty($item->birthday)) { return null; } return now()->diffInYears(Carbon::parse($item->birthday)); })->map(fn ($group) => $group->count()) ->sortKeys();
该方案不需要写任何SQL原生表达式,但需要将所有符合条件的数据加载到内存处理,数据量大时性能远低于SQL层面计算,且无法直接利用数据库的索引优化。
内容的提问来源于stack exchange,提问作者Mohsen
相关产品推荐
相关产品推荐

