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

如何提升Laravel旧查询可读性?移除CAST(SUBSTRING_INDEX)写法

优化Laravel Eloquent查询的可读性与替换CAST(SUBSTRING_INDEX)方案

一、提升查询可读性的方法

  1. 使用Eloquent模型与关联关系
    定义对应模型(Game、Result、UsersTeam)并设置关联,替代直接调用DB::table,让查询逻辑更贴合业务语义:

    • Game模型添加hasMany(Result::class)关联
    • Result模型添加belongsTo(Game::class)和belongsTo(User::class)关联
    • UsersTeam模型添加belongsTo(User::class)关联
  2. 拆分复杂条件,封装局部作用域
    将时间、分数范围的判断逻辑封装为Game模型的局部作用域,让主查询代码更简洁,逻辑模块化。

  3. 格式化代码与添加注释
    保持代码缩进一致,每个查询方法单独成行,添加必要注释说明业务逻辑,降低理解成本。

二、替换CAST(SUBSTRING_INDEX)的最优方案

推荐:修改数据库结构

原写法的核心问题是将数值范围存储为-分隔的字符串,既影响查询性能,又增加代码复杂度。最优方案是拆分字段:

  • 将games表的min_max_algorithm_time拆分为min_algorithm_time(DECIMAL(10,2))和max_algorithm_time(DECIMAL(10,2))
  • 将min_max_algorithm_score拆分为min_algorithm_score(DECIMAL(10,2))和max_algorithm_score(DECIMAL(10,2))

拆分后可直接进行数值比较,无需字符串处理,性能和可读性均大幅提升。

临时方案(无法修改数据库时)

若暂时无法调整数据库结构,可将拆分逻辑封装为可复用的片段,避免重复编写冗长的CAST(SUBSTRING_INDEX)代码。

优化后的代码示例

情况1:已修改数据库结构(推荐)

// Game模型中定义局部作用域
public function scopeWithValidAlgorithmResults($query)
{
    return $query->where(function ($q) {
        $q->whereNull('min_algorithm_time')
          ->orWhere(function ($q) {
              $q->whereColumn('results.time', '>=', 'games.min_algorithm_time')
                ->whereColumn('results.time', '<=', 'games.max_algorithm_time');
          });
    })->where(function ($q) {
        $q->whereNull('min_algorithm_score')
          ->orWhere(function ($q) {
              $q->whereColumn('results.score', '>=', 'games.min_algorithm_score')
                ->whereColumn('results.score', '<=', 'games.max_algorithm_score');
          });
    });
}

// 主查询代码
Game::select('games.*')
    ->join('results', 'games.id', '=', 'results.game_id')
    ->join('users_teams', 'users_teams.user_id', '=', 'results.user_id')
    ->withValidAlgorithmResults()
    ->where('users_teams.team_id', $teamId)
    ->where('users_teams.is_player', 1)
    ->groupBy('games.id')
    ->get()
    ->toArray();

情况2:未修改数据库结构

DB::table('games AS g')
    ->select('g.*')
    ->join('results AS r', 'g.id', '=', 'r.game_id')
    ->join('users_teams AS ut', 'ut.user_id', '=', 'r.user_id')
    // 拆分时间范围条件,提升可读性
    ->where(function ($query) {
        $query->whereNull('g.min_max_algorithm_time')
              ->orWhere(function ($query) {
                  $query->whereRaw('r.time >= CAST(SUBSTRING_INDEX(g.min_max_algorithm_time, "-", 1) AS DECIMAL(10,2))')
                        ->whereRaw('r.time <= CAST(SUBSTRING_INDEX(g.min_max_algorithm_time, "-", -1) AS DECIMAL(10,2))');
              });
    })
    // 拆分分数范围条件
    ->where(function ($query) {
        $query->whereNull('g.min_max_algorithm_score')
              ->orWhere(function ($query) {
                  $query->whereRaw('r.score >= CAST(SUBSTRING_INDEX(g.min_max_algorithm_score, "-", 1) AS DECIMAL(10,2))')
                        ->whereRaw('r.score <= CAST(SUBSTRING_INDEX(g.min_max_algorithm_score, "-", -1) AS DECIMAL(10,2))');
              });
    })
    ->where('ut.team_id', $teamId)
    ->where('ut.is_player', 1)
    ->groupBy('g.id')
    ->get()
    ->toArray();

内容的提问来源于stack exchange,提问作者Mohsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:02:43