我需要选择与当前用户相反的u1或u2并将其内部加入,以显示具有正确图片/ id的正确朋友列表
输入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 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
------------------------------------------------------------------
答案 0 :(得分:2)
假设关系是从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_fk
和u2_fk
重命名为user_id
和friend_id
。
答案 1 :(得分:2)
以下查询应该可以解决问题:
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
代表当前会话ID的users
记录,u2
被JOIN
插入为关系另一端的用户。
此 demo on DB Fiddle 和您的示例数据返回,会话ID为1
:
| id | u1 | u2 | userid | username | picture |
| --- | --- | --- | ------ | --------------- | ----------- |
| 1 | 1 | 2 | 2 | anotherusername | another.jpg |
| 1 | 3 | 1 | 3 | thirdusername | third.jpg |