首页 > 解决方案 > 如何从表中 1 正确的 2 个值中 INNER JOIN 正确的 VALUE

问题描述

我需要选择并在当前用户的对面加入正确的 u1 或 u2 以显示具有正确图片/id 的正确朋友列表

会话编号

$sess_id = $_SESSION['user']['id'];

关系表

id      u1_fk    u2_fk     u_action     status
-------------------------------------------------
 1       1        2            2          5
-------------------------------------------------
 1       3        1            3          5

细节:

用户表

user_id    user_username          user_picture
-------------------------------------------------
 1           someusername           me.jpg       
-------------------------------------------------
 2           anotherusername      another.jpg
-------------------------------------------------
 3           thirdusername         third.jpg

SQL + PHP(这里我在 user_id 上 INNER JOIN u_action):

$sql = "SELECT t1.id as id, "
        . " t1.u1_fk as u1, "
        . " t1.u2_fk as u2, "
        . " t2.user_id as userid, "
        . " t2.user_username as username, "
        . " t2.user_picture as picture "
        . " FROM relationships t1 "
        . " INNER JOIN users t2 "
        . " ON t1.u_action = t2.user_id "
        . " WHERE (t1.u1_fk = :user_one "
        . " OR t1.u2_fk = :user_two) "
        . " AND t1.relationship_status = 5 ";

$stmt = $dbCon->prepare($sql);
$stmt->bindParam(":user_one", $sess_id);
$stmt->bindParam(":user_two", $sess_id);
$stmt->execute();
$count = $stmt->rowCount();
if ($count > 0) {
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

我以为我可以使用u_action,但这显然只适用于其中一个,因为它是存储在该字段中的 2 个用户 ID 之一。

那么我怎么知道我的查询何时应该内连接u1u2,我在这里有点困惑我希望有人能帮助我,我正在考虑做 2 个查询并对所有结果进行排序并删除用户自己的 id 并做一个 where in第二个查询中的子句,但是我想知道这是否可以仅在 1 个查询中完成。

数据库的结果应该是什么样子

在这个 sess_id 为的特定示例中,我希望从数据库中得到什么1

id      u1_fk    u2_fk      userid     username         picture
------------------------------------------------------------------
 1       1        2            2     anotherusername   another.jpg
------------------------------------------------------------------
 1       3        1            3      thirdusername     third.jpg

在这个 sess_id 为 = 2 的特定示例中,我想要从数据库中得到什么

id      u1_fk    u2_fk      userid     username         picture
------------------------------------------------------------------
 1       1        2            2     someusername   me.jpg
------------------------------------------------------------------

标签: phpmysqlsql

解决方案


假设关系是单向的,从 U1 到 U2,那么很简单:

select u.*
from relationships r
inner join users u on r.u2_fk = u.id
where r.u1_fk = ?

我不知道行动或状态是什么意思。

如果您在关系表中使您的 dB 字段更具描述性:即 user_id 和friend_id,则可以更清楚地说明这一点。然后很明显你想将relationship.friend_id加入user.id,并通过relationship.user_id过滤

然后您还可以按状态等进行过滤。


由于您已经添加了所需的结果,我看到您希望在结果中同时包含 u1_fk 和 u2_fk。这当然可以做到,但你这样做会更加混乱,IMO。

我建议当接受友谊时,为新朋友创建一条新线路。这样,当你想找到一个用户的所有好友时,你只需要匹配 u1_fk(即 user_id),好友永远是 u2_fk(friend_id)。

然后,每个朋友都可以独立控制他们想如何关联,即你可以阻止我,或者我可以阻止你。——我的两分钱值。让你的协会做一件事。


查看架构可能会有所帮助:

User    Relationship    User
           id
id ---->  u1_fk
          u2_fk <------- id

这很容易弄清楚。但你想要的更像是

User    Relationship    User
           id
 id -----> u1_fk <------ id
     \---> u2_fk <---/

因此,首先,我从按关系过滤的角度来看待它,然后在匹配时添加用户信息:

select r.id, r.u1_fk, r.u2_fk, 
       coalesce(u1.user_id, u2.user_id) userid,
       coalesce(u1.username, u2.username) username,
       coalesce(u1.user_picture, u2.user_picture) picture
from relationship r
left join user u1 on r.u1_fk = u1.id
left join user u2 on r.u1_fk = u2.id
where u1_fk = ? or u2_fk = ?

但这意味着您必须合并来自 u1 和 u2 的字段。

另一种解决方案是从用户开始,加入所有可能的关系,然后与不是你开始的用户的用户加入(GMB 的优雅解决方案)

但是,如果您有以下情况会发生什么:

id    u1_fk    u2_fk
        1        2
        2        1

我认为这两种解决方案都会给你一个重复的列表。

这就是为什么我强烈鼓励您重命名(至少在您的脑海中) u1_fku2_fkto user_idand friend_id


推荐阅读