Left Join 查询返回错误结果

Posted

技术标签:

【中文标题】Left Join 查询返回错误结果【英文标题】:Left Join query return bad results 【发布时间】:2015-02-24 09:11:42 【问题描述】:

我已经尝试了几个小时来使用 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 查询的情况下做到这一点。

【问题讨论】:

【参考方案1】:

我知道这个问题已经有一个可接受的答案,但我想添加这个...

有一种 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;

【讨论】:

嗯……太好了!我会尽快尝试并给你反馈!谢谢!【参考方案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.

【讨论】:

【参考方案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

【讨论】:

以上是关于Left Join 查询返回错误结果的主要内容,如果未能解决你的问题,请参考以下文章

mybatis使用left-join查询结果总是一对一的

多表查询-inner join left join right joinfull join

MySql 之 left join 查询结果

从 LEFT JOIN 列获取最新结果

访问 SQL LEFT JOIN 不返回结果

sql left join - 如果没有结果,则返回默认值