Left Join查询返回错误结果

时间:2014-12-27 13:16:01

标签: mysql sql select join laravel

我一直在努力用MySQL进行左连接查询 我有一个名为“at_friends”的表格,用于存储用户之间的关系。

id  |  id_user1 |  id_user2  |  accepted
1   |  2        |  1         |  1
2   |  1        |  3         |  0

这意味着用户1是用户2的朋友,用户1向用户3发送了朋友请求。

这是我的表“at_users”

id  |  name
1   |  "John"   
2   |  "Mike"   
3   |  "Bob"    

我尝试过这个问题:

SELECT at_users.id, at_users.name
    FROM at_users 
    LEFT JOIN at_friends
         ON at_friends.id_user1 = at_users.id
         OR at_friends.id_user2 = at_users.id
         AND at_friends.accepted = 1
    WHERE id_user1 = 1 OR id_user2 = 1

“1”是当前用户(John)的唯一ID


但我得到了这些结果

id  |  name
1   |  "John"   
2   |  "Mike"   
1   |  "John"    

我想要的是用户n°1的已接受朋友的列表。
顺便说一句,我使用Laravel,但我不知道是否有办法在没有自定义mysql查询的情况下执行此操作。

3 个答案:

答案 0 :(得分:3)

试试这个:

SELECT u.id, u.name
FROM at_users u 
INNER JOIN (SELECT id_user2 AS friendID FROM at_friends WHERE id_user1 = 1 AND accepted = 1
            UNION 
            SELECT id_user1 AS friendID FROM at_friends WHERE id_user2 = 1 AND accepted = 1
           ) AS A ON u.id = A.friendID

答案 1 :(得分:2)

另一种只需要对朋友表进行一次扫描的替代方案:

SELECT u.id, u.name
FROM at_users u 
JOIN at_friends f
  ON 1 in (f.id_user1, f.id_user2) and
     u.id = case f.id_user1 when 1 then id_user2 else id_user1 end and 
     f.accepted=1

SQLFiddle here.

答案 2 :(得分:2)

我知道这个问题已经有了接受的答案,但我想补充一下......

有一种Laravel方式!

将此辅助方法添加到User模型

public function friends(){
    $id = $this->id;
    return $this->join('at_friends', function($q) use ($id){
        $q->on('at_friends.id_user2', '=', 'users.id');
        $q->where('at_friends.id_user1', '=', $id);
        $q->orOn('at_friends.id_user1', '=', 'users.id');
        $q->where('at_friends.id_user2', '=', $id);
    });
}

以下是如何使用它

$user = User::find(1);
$user->friends()->where('accepted', true)->get();

如果您愿意,可以将此属性访问者添加到模型中:

public function getFriendsAttribute(){
    return $this->friends()->where('accepted', true)->get();
}

并使用它:

$user->friends;