如何通过Laravel Eloquent执行这个复杂的查询


How to execute this complex query through Laravel Eloquent?

我在SQL中有这个复杂的查询:

SELECT distinct(albumId) as id,
band,albumName as name,
SUM(numberOfPlays) as numberOfPlays
FROM (
SELECT COUNT(*) as numberOfPlays,
tracks.album_id as albumId,
a.name as albumName,b.name as band
FROM logs l
LEFT JOIN tracks ON tracks.id=l.track_id
LEFT JOIN albums a ON tracks.album_id = a.id
LEFT JOIN bands b ON b.id = tracks.band_id
WHERE l.time>$days
GROUP by trackid
ORDER BY numberOfPlays DESC LIMIT 0,100) t
GROUP BY albumId ORDER BY numberOfPlays DESC");

到目前为止,我已经使用以下命令成功检索了内部查询:

Logs::select(DB::raw(
                    'COUNT(*) as numberOfPlays'
                ), 'track_id')
               ->where('time', '>', $days)
               ->orderBy('numberOfPlays', 'DESC')->take(100)
               ->with('track', 'track.album')
               ->groupBy('DB::raw("track_id"))->orderBy('numberOfPlays', 'DESC');

如何对上述查询返回的数据运行进一步查询?

您实际上可以通过 Eloquent ORM 并利用返回的集合结果上可用的方法获得类似的结果。下面是一个示例。考虑到您拥有所有模型类。

$logs = Log::with(['track.album', 'track.band'])->where('time', '>', $days)->take(100)get();


class Log extends Eloquent {
   public function track() {
      return $this->belongsTo('Track');
   }
}

Class Track extends Eloquent {
   public function album() {
     return $this->belongsTo('Album');
   }
   public function band() {
     return $this->belongsTo('Band');
   }
}
Class Album extends Eloquent {
}

Class Band extends Eloquent {}

现在,若要按所需方式生成结果,可以使用返回的集合将其项转换为可呈现的结构。

首先,我们将按相册对日志进行分组

$logsByAlbum = $logs->groupBy('track.album.id');

然后转换分组日志

$logsByAlbum->transform(function($album_logs) {
    if(!empty($album_logs)) {
      return array(
        'id' => $album_logs[0]->album->id,
        'album_name' => $album_logs[0]->album->name,
        'numberOfPlays' => count($album_logs)
      );
    }
    return array();
});
After transformation, we need to filter the items with empty values
$final_result = $logsByAlbum->filter(function($item) { 
      return !empty($item);
});
return $final_result->toArray();

这只是一个基本的想法,以帮助您使用雄辩的ORM和集合类中提供的方法的强大功能。

享受! :D