Laravel Eloquent/QueryBuilder 多个嵌套选择
Laravel Eloquent/QueryBuilder Multiple Nested Selects
我如何在 eloquent/query 生成器中编写这样的查询?有多个嵌套 select 语句并带有连接的查询。
任何帮助将不胜感激。
Select
s.user_id,
s.user_name,
s.`user_firstname`,
s.`user_lastname`,
s.user_photo,
max_rank_timestamp,
max_friend_timestamp
FROM
(
SELECT
Users.user_id,
Users.`user_name`,
Users.`user_firstname`,
Users.`user_lastname`,
`Users`.`user_photo`,
MAX(Ranks.rank_timestamp) AS max_rank_timestamp
FROM
`Users`
LEFT JOIN Ranks ON Ranks.user_id = Users.user_id
WHERE
Users.user_is_active = 1
GROUP BY
Users.user_id
) s
LEFT JOIN (
SELECT
Users.user_id,
MAX(Relationship.timestamp) AS max_friend_timestamp
FROM
`Users`
INNER JOIN Relationship ON Relationship.user_one_id = Users.user_id
WHERE
Users.user_is_active = 1
GROUP BY
Users.user_id
) p ON s.user_id = p.user_id
) t
ORDER BY
`user_name` ASC
用户模型
public function ranks(){
return $this->hasMany('App\Rank','user_id','user_id');
}
public function relationships(){
return $this->hasMany('App\Relationship','user_one_id','user_id');
}
排名模型
public function user(){
return $this->belongsTo('App\User','user_id','user_id');
}
关系模型
public function user(){
return $this->belongsTo('App\User','user_id','user_one_id');
}
您可以这样做的一种方法是将以下范围添加到您的 User
模型中:
public function scopeWithMaxRankTimestamp(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->ranks();
});
$q = $this->ranks()->getRelationExistenceQuery(
$relation->getRelated()->newQuery(), $query, new Expression('MAX(rank_timestamp)')
);
$query->selectSub($q->toBase(), 'max_rank_timestamp');
}
public function scopeWithMaxFriendTimestamp(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->relationships();
});
$q = $this->relationships()->getRelationExistenceQuery(
$relation->getRelated()->newQuery(), $query, new Expression('MAX(timestamp)')
);
$query->selectSub($q->toBase(), 'max_friend_timestamp');
}
上面假设 Ranks
table 的关系是 ranks()
而 Relationship
table 的关系是 relationships()
。
要使上述工作正常,您还需要将以下 use
语句添加到 class 的顶部:
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Expression;
然后你可以像这样使用你的结果:
$users = User::withMaxRankTimestamp()
->withMaxFriendTimestamp()
->where('user_is_active', 1)
->orderBy('user_name')
->get();
希望对您有所帮助!
我如何在 eloquent/query 生成器中编写这样的查询?有多个嵌套 select 语句并带有连接的查询。 任何帮助将不胜感激。
Select
s.user_id,
s.user_name,
s.`user_firstname`,
s.`user_lastname`,
s.user_photo,
max_rank_timestamp,
max_friend_timestamp
FROM
(
SELECT
Users.user_id,
Users.`user_name`,
Users.`user_firstname`,
Users.`user_lastname`,
`Users`.`user_photo`,
MAX(Ranks.rank_timestamp) AS max_rank_timestamp
FROM
`Users`
LEFT JOIN Ranks ON Ranks.user_id = Users.user_id
WHERE
Users.user_is_active = 1
GROUP BY
Users.user_id
) s
LEFT JOIN (
SELECT
Users.user_id,
MAX(Relationship.timestamp) AS max_friend_timestamp
FROM
`Users`
INNER JOIN Relationship ON Relationship.user_one_id = Users.user_id
WHERE
Users.user_is_active = 1
GROUP BY
Users.user_id
) p ON s.user_id = p.user_id
) t
ORDER BY
`user_name` ASC
用户模型
public function ranks(){
return $this->hasMany('App\Rank','user_id','user_id');
}
public function relationships(){
return $this->hasMany('App\Relationship','user_one_id','user_id');
}
排名模型
public function user(){
return $this->belongsTo('App\User','user_id','user_id');
}
关系模型
public function user(){
return $this->belongsTo('App\User','user_id','user_one_id');
}
您可以这样做的一种方法是将以下范围添加到您的 User
模型中:
public function scopeWithMaxRankTimestamp(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->ranks();
});
$q = $this->ranks()->getRelationExistenceQuery(
$relation->getRelated()->newQuery(), $query, new Expression('MAX(rank_timestamp)')
);
$query->selectSub($q->toBase(), 'max_rank_timestamp');
}
public function scopeWithMaxFriendTimestamp(Builder $query)
{
if (is_null($query->getQuery()->columns)) {
$query->select([$query->getQuery()->from . '.*']);
}
$relation = Relation::noConstraints(function () {
return $this->relationships();
});
$q = $this->relationships()->getRelationExistenceQuery(
$relation->getRelated()->newQuery(), $query, new Expression('MAX(timestamp)')
);
$query->selectSub($q->toBase(), 'max_friend_timestamp');
}
上面假设 Ranks
table 的关系是 ranks()
而 Relationship
table 的关系是 relationships()
。
要使上述工作正常,您还需要将以下 use
语句添加到 class 的顶部:
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Expression;
然后你可以像这样使用你的结果:
$users = User::withMaxRankTimestamp()
->withMaxFriendTimestamp()
->where('user_is_active', 1)
->orderBy('user_name')
->get();
希望对您有所帮助!