php - 如何从表中 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
细节:
Id
是自动递增 idu1_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
------------------------------------------------------------------
解决方案
假设关系是单向的,从 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
to user_id
and friend_id
。
推荐阅读
- git - 如何通过 git bash 在 github 远程仓库上删除没有扩展名的文件(二进制可执行文件)?
- tensorflow - tf.reduce_sum(tf.square(output_vector), axis, keep_dims=True) 在做什么?
- mysql - 通过python在mysql选择器中产生无效结果
- authentication - 加载 ntuser.dat 之前的 Winlogon 通知服务
- python - 如何在 Python 中使用 SQLAlchemy 映射子对象?
- python - django url 不匹配
- java - HashMap Java 中的 HashMap
- java - 如何存储不合理的 BigDecimal
- java - 将摩尔斯电码转换为英语词典单词
- javascript - 删除 Firestore 中的文档和 Storage 中的文件