【问题标题】:Laravel mysql Inner join and also select a specific field from another tableLaravel mysql内部连接并从另一个表中选择特定字段
【发布时间】:2018-01-07 12:55:05
【问题描述】:

我有以下疑问:

Ratings::join('users', 'movieratings.rated_by', '=', 'users.usr_id')
        ->where('rated_on', $movieId)
        ->orderBy('rated_at', 'desc')
        ->select('comment', 'rating', 'rated_as', 'rated_at', 'username')
        ->paginate(20);

这将获得特定电影的所有反馈评级。 但我有另一个表,其中包含特定电影的总好坏评分,唯一的问题是我无法让它同时查询该表。

如果我做另一个查询,我会简单地写:Movie::where('movie_id', $movieId)->select('total_good_ratings', 'total_bad_ratings')->get(); 这将输出例如 "22, 15" 但是否可以只从特定行中获取两列然后进行内部连接在两个表之间并分页结果?

谢谢

【问题讨论】:

  • 为什么不直接使用普通的 Eloquent 关系而不是 join?这样就容易多了。
  • @apokryfos 主要是因为我不确定当我调用一些 laravel 辅助函数时会发生什么。我发现编写原始 sql 更容易,只要它们在大多数情况下都是安全的

标签: php mysql laravel eloquent inner-join


【解决方案1】:

您可以对包含好评和差评的表执行 leftJoin,其中加入条件将是电影的 id。

Ratings::join('users', 'movieratings.rated_by', '=', 'users.usr_id')
        ->leftJoin('movie', 'movie.id', '=', 'movieratings.rated_on')
        ->where('rated_on', $movieId)
        ->orderBy('rated_at', 'desc')
        ->select('comment', 'rating', 'rated_as', 'rated_at', 'username', 'total_good_ratings', 'total_bad_ratings')
        ->paginate(20);

【讨论】:

  • 这意味着可以在没有评分的情况下进行评分。
  • 如何在选择字段中添加别名?
【解决方案2】:

我想你可以试试这个:

Ratings::leftJoin('users', 'users.usr_id', '=', 'movieratings.rated_by')
        ->leftJoin('movie', 'movie.id', '=', 'movieratings.rated_on')
        ->where('movieratings.rated_on', $movieId)
        ->orderBy('movie.rated_at', 'desc')
        ->select('movieratings.comment', 'movieratings.rating', 'movieratings.rated_as', 'movie.rated_at', 'users.username', 'movieratings.total_good_ratings', 'movieratings.total_bad_ratings')
        ->paginate(20);

希望对你有帮助!!!

【讨论】:

    【解决方案3】:

    如果这可能有帮助:

    假设:

    class Rating extends Model {
          public users() {
              $this->belongsTo(User::class, 'usr_id');
          }
          public movie() {
              $this->belongsTo(Movie::class, 'rated_on'); //Name looks odd, it should be movie_id if you are following standard conventions
          }
    }
    

    然后你可以延迟/重新加载它们:

    $ratings = Ratings::with([ "movie" => function ($query) {
            $q->select('total_good_ratings', 'total_bad_ratings');
         }])->where('rated_on', $movieId)
           ->orderBy('rated_at', 'desc')
           ->select('comment', 'rating', 'rated_as', 'rated_at', 'username',"rated_on")
           ->paginate(20);
    

    您可以通过$ratings[X]->movie->total_good_ratings 获取电影信息(循环中为$rating->movie->total_good_ratings

    虽然有点批评:

    1. total_good_ratings 看起来像是一个派生属性,所以它不应该首先存储。这似乎是对良好收视率的计数。
    2. 在命名列和表时应使用标准约定,例如外键通常称为 <foreign table name in singular>_<foreign field name> 例如 user_idmovie_id

    【讨论】:

      猜你喜欢
      • 2020-10-08
      • 2020-08-17
      • 2011-05-17
      • 2023-03-03
      • 1970-01-01
      • 2020-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多