[英]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之一。
所以我怎么知道我的查询应该内部加入u1
或u2
,我在这里有点困惑我希望有人可以帮助我,我想做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_fk
和u2_fk
重命名(至少在你的脑海中)为user_id
和friend_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记录,和u2
是JOIN
在作为上的关系的另一端的用户编辑。
这个关于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.