繁体   English   中英

如何从1中正确的表中的2个值INNER JOIN正确的VALUE

[英]How to INNER JOIN the correct VALUE from 2 values in the table where 1 is correct

我需要选择和内部加入正确的u1或u2,与当前用户相反,以正确的图片/ id显示正确的朋友列表

Sess id

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

关系表

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

细节:

  • Id是自动增量ID
  • u1_fk是第一个参与的用户ID(提交了好友请求)
  • u2_fk是另一个用户的id(获得好友请求的人)
  • u_action是最后一个做出动作的用户(等发送好友请求,拒绝/接受好友请求,阻止其他用户等等)

用户表

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子句中,我想知道是否可以在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
------------------------------------------------------------------

假设关系是单向的,从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,并按关系过滤.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_fk重命名(至少在你的脑海中)为user_idfriend_id

以下查询应该可以解决问题:

SELECT
    r.id as id,
    r.u1_fk as u1,
    r.u2_fk as u2,
    u2.user_id as userid,
    u2.user_username as username,
    u2.user_picture as picture
FROM 
    users u1
    INNER JOIN relationship r 
        ON  r.status = 5
        AND (r.u1_fk = u1.user_id OR r.u2_fk = u1.user_id)
    INNER JOIN users u2
        ON  u2.user_id <> u1.user_id
        AND (r.u1_fk = u2.user_id OR r.u2_fk = u2.user_id) 
WHERE 
    u1.user_id = :sessid

u1表示users为当前会话ID记录,和u2JOIN在作为上的关系的另一端的用户编辑。

这个关于DB Fiddle的演示,带有示例数据返回,对于会话ID 1

| id  | u1  | u2  | userid | username        | picture     |
| --- | --- | --- | ------ | --------------- | ----------- |
| 1   | 1   | 2   | 2      | anotherusername | another.jpg |
| 1   | 3   | 1   | 3      | thirdusername   | third.jpg   |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM