我如何在 Laravel Eloquent 中编写此 MySQL 查询?
How would I code this MySQL query in Laravel Eloquent?
我正在尝试使用半复杂查询(无论如何按照我的标准),但我想不出如何使用查询生成器或使用 eloquent 关系来完成它。
我的人际关系table是:user_id_1 | user_id_2 | status | action_user_id
朋友的话,action_user_id
和status = 1
可以忽略。每个关系只有一行,因此如果您想要 select 属于用户 17 的所有关系,那么您需要同时检查 user_id_1 和 user_id_2,因为 ID 可以在任一列中。我从这里开始遵循数据库结构:http://www.codedodle.com/2015/03/social-network-friends-relationship.html
我要执行的查询类型是:
SELECT users.*
FROM users
LEFT JOIN users_relationships AS r
ON (
users.id = r.user_id_1
AND r.user_id_1 != $user_id
) OR (
users.id = r.user_id_2
AND r.user_id_2 != $user_id
)
WHERE r.status = 1
AND (
r.user_id_1 = $user_id
OR r.user_id_2 = $user_id
)
这样的事情在 eloquent 关系中最好,所以它很容易执行:$user->friends
它会 return 以上结果,但我被卡住了在各个方向。
不幸的是,我最好的尝试没有使用关系是这样的:
User::with('profile')->join('user_relationships as r', function($join) use ($user_id) {
$join->on(DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
$join->orOn(DB::raw('( users.id = r.user_id_2 AND r.user_id_2 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
然而,这给了我与参数相关的错误:
SQLSTATE[HY093]: Invalid parameter number (SQL: select `users`.* from `users` inner join `user_relationships` as `r` on ( users.id = r.user_id_1 AND r.user_id_1 != 1 ) or ( users.id = r.user_id_2 AND r.user_id_2 != 30 ) where `users`.`deleted_at` is null and `r`.`status` = 30 and (`r`.`user_id_1` = ? or `r`.`user_id_2` = ?))
我不确定如何做我想做的事。
问题出在这里:
DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id])
DB::raw() 不采用第二个参数进行绑定。使用 ->on()->where()
代替(感谢 user4621032):
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
因此,要根据需要设置 ->friends()
函数,您可以使用:
public function friends()
{
$user_id = $this->id;
return self::with('profile')
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
}
可能是这样
DB::table('users')
->leftJoin('users_relationships AS r', function($join) use($user_id){
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status',1)
->where('r.user_id_1','=',$user_id)
->orWhere('r.user_id_2','=',$user_id)
->get();
我正在尝试使用半复杂查询(无论如何按照我的标准),但我想不出如何使用查询生成器或使用 eloquent 关系来完成它。
我的人际关系table是:user_id_1 | user_id_2 | status | action_user_id
朋友的话,action_user_id
和status = 1
可以忽略。每个关系只有一行,因此如果您想要 select 属于用户 17 的所有关系,那么您需要同时检查 user_id_1 和 user_id_2,因为 ID 可以在任一列中。我从这里开始遵循数据库结构:http://www.codedodle.com/2015/03/social-network-friends-relationship.html
我要执行的查询类型是:
SELECT users.*
FROM users
LEFT JOIN users_relationships AS r
ON (
users.id = r.user_id_1
AND r.user_id_1 != $user_id
) OR (
users.id = r.user_id_2
AND r.user_id_2 != $user_id
)
WHERE r.status = 1
AND (
r.user_id_1 = $user_id
OR r.user_id_2 = $user_id
)
这样的事情在 eloquent 关系中最好,所以它很容易执行:$user->friends
它会 return 以上结果,但我被卡住了在各个方向。
不幸的是,我最好的尝试没有使用关系是这样的:
User::with('profile')->join('user_relationships as r', function($join) use ($user_id) {
$join->on(DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
$join->orOn(DB::raw('( users.id = r.user_id_2 AND r.user_id_2 != ? )', [$user_id]), DB::raw(''), DB::raw(''));
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
然而,这给了我与参数相关的错误:
SQLSTATE[HY093]: Invalid parameter number (SQL: select `users`.* from `users` inner join `user_relationships` as `r` on ( users.id = r.user_id_1 AND r.user_id_1 != 1 ) or ( users.id = r.user_id_2 AND r.user_id_2 != 30 ) where `users`.`deleted_at` is null and `r`.`status` = 30 and (`r`.`user_id_1` = ? or `r`.`user_id_2` = ?))
我不确定如何做我想做的事。
问题出在这里:
DB::raw('( users.id = r.user_id_1 AND r.user_id_1 != ? )', [$user_id])
DB::raw() 不采用第二个参数进行绑定。使用 ->on()->where()
代替(感谢 user4621032):
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
因此,要根据需要设置 ->friends()
函数,您可以使用:
public function friends()
{
$user_id = $this->id;
return self::with('profile')
->leftJoin('users_relationships AS r', function($join) use($user_id) {
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status', 1)
->where(function($query) use ($user_id) {
$query->where('r.user_id_1', $user_id)
->orWhere('r.user_id_2', $user_id);
})
->get(['users.*']);
}
可能是这样
DB::table('users')
->leftJoin('users_relationships AS r', function($join) use($user_id){
$join->on('users.id','=','r.users_id_1')->where('r.users_id_1','!=',$user_id)
->orOn('users_id','=','r.users_id_2')->where('r.users_id_2','!=',$user_id);
})
->where('r.status',1)
->where('r.user_id_1','=',$user_id)
->orWhere('r.user_id_2','=',$user_id)
->get();