我有这个适用于MySQL的SQL查询,它工作正常。但是我需要使用查询生成器重写它,并且需要完全避免使用DB::raw()
,因为开发数据库与生产环境不同。我知道远非理想,但不幸的是它是什么。
SELECT athletes.*,
(
SELECT performance
FROM performances
WHERE athletes.id = performances.athlete_id AND performances.event_id = 1
ORDER BY performance DESC
LIMIT 0,1
) AS personal_best
FROM athletes
ORDER BY personal_best DESC
Limit 0, 100
而且我在努力重写personal_best
部分。我有运动员的表现表,我只需要选择每个运动员的最佳表现作为他个人的最佳表现。
我试图搜索答案,但是发现的所有答案都包括原始添加原始SQL。
任何想法或提示将不胜感激。
提前谢谢!
因此,我接受了为此可能不得不使用Eloquent的想法,但是仍然很难进行。这是我的代码:
class Athlete extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'athletes';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
/**
* Get the performances for the Athelete post.
*
* @return HasMany
*/
public function performances()
{
return $this->hasMany('App\EloquentModels\Performance', 'athlete_id');
}
}
class Performance extends Model
{
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'performances';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
答案 0 :(得分:3)
在database.php
上新建一个连接,如mysql_dev作为开发参数。
DB::connection('mysql_dev')->table('athletes')
->leftJoin('performances','athletes.id','performances.athlete_id')
->where('performances.event_id',1)
->groupBy('athletes.id')
->orderByDesc('personal_best')
->select('athletes.*',DB::raw('MAX(performances.performance) AS personal_best')
->paginate(100);
不加尝试地尝试这种方法
DB::connection('mysql_dev')->table('athletes')
->leftJoin('performances','athletes.id','performances.athlete_id')
->where('performances.event_id',1)
->groupBy('athletes.id')
->orderByDesc('performances.performance')
->select('athletes.*','performances.performance'
->paginate(100);
答案 1 :(得分:2)
如果您使用的是原始SQL,则只需MAX
对使用GROUP BY
的每个运动员进行性能测试。
SELECT athletes.*, MAX(performance) AS personal_best
FROM athletes
INNER JOIN performances ON athletes.id = performances.athlete_id AND performances.event_id = 1
GROUP BY athletes.id
ORDER BY personal_best DESC
LIMIT 0, 100
Laravel查询生成器:
DB::table('athletes')
->join('performances', 'athletes.id', '=', 'performances.athlete_id')
->where('performances.event_id', '=', 1)
->groupBy('athletes.id')
->orderBy('personal_best', 'desc')
->select('athletes.*',DB::raw('MAX(performance) AS personal_best')
->limit(100);
Doc说我们可以做max(personal_best)
,但不确定如何与group by一起使用。
恐怕您不能在查询生成器中避免使用DB::raw
,但是您可以使用eloquent model
来实现此目的,正如Shaielndra Gupta
回答的那样。
为此,您可以创建模型和关系。
1. Create Model:
php artisan make:model Athelete
php artisan make:model Performance
2. Create relationship between Athelete and Perforamnce.
Update Athelete.php
/**
* Get the performances for the Athelete post.
*/
public function performances()
{
return $this->hasMany('App\Performance');
}
3. Get data(didn't verify by myself)
$data = Athelete::with('performances',function ($query) use ($eventId){
$query->max('performance')
$query->where('event_id',$eventId)
$query->orderBy('performance');
})->get();
参考:
答案 2 :(得分:0)
您可以按以下方式使用。
$sql1 = "(
SELECT performance
FROM performances
WHERE athletes.id = performances.athlete_id AND performances.event_id = 1
ORDER BY performance DESC
LIMIT 0,1
) AS personal_best";
$sql2 = "SELECT athletes.*,$sql1
FROM athletes
ORDER BY personal_best DESC
Limit 0, 100";
$result = DB::select($sql2);
答案 3 :(得分:0)
您可以像这样使用Eloquent ORM
$data = Athelete::with('performances',function ($query) use ($eventId){
$query->max('performance')
$query->where('event_id',$eventId)
$query->orderBy('performance');
})->get()