Laravel 查询生成器 - select 来自另一个 table 的前 1 行
Laravel Query builder - select top 1 row from another table
我有一个 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
部分。我有 table 个运动员的表现,我只需要 select 每个运动员的最佳表现作为他的个人最好成绩。
我试图寻找答案,但我找到的所有答案都包括原始添加原始 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;
}
如果您使用的是原始 SQL,只需使用 GROUP BY
.
对每个运动员的表现进行 MAX
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)
但不确定如何将其与分组依据一起使用。
恐怕您无法在查询生成器中避免使用 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();
参考:
您可以像下面这样使用。
$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);
在 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);
你可以像这样使用 Eloquent ORM
$data = Athelete::with('performances',function ($query) use ($eventId){
$query->max('performance')
$query->where('event_id',$eventId)
$query->orderBy('performance');
})->get()
我有一个 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
部分。我有 table 个运动员的表现,我只需要 select 每个运动员的最佳表现作为他的个人最好成绩。
我试图寻找答案,但我找到的所有答案都包括原始添加原始 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;
}
如果您使用的是原始 SQL,只需使用 GROUP BY
.
MAX
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)
但不确定如何将其与分组依据一起使用。
恐怕您无法在查询生成器中避免使用 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();
参考:
您可以像下面这样使用。
$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);
在 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);
你可以像这样使用 Eloquent ORM
$data = Athelete::with('performances',function ($query) use ($eventId){
$query->max('performance')
$query->where('event_id',$eventId)
$query->orderBy('performance');
})->get()