我正在与朋友创建一种社交网站,我有用户和朋友关系的表格
FRIENDS
id iduser idfriend
0 44 56
1 44 102
2 10 66
3 10 85
4 44 10
5 10 44
6 56 44
LOGIN
id jmeno email isonline
44 john john@gmail.com 1
10 joe joe@yahoo.com 1
185 mark mark@so.com 0
当用户连接他从服务器请求他的在线朋友时,我使用这个SQL命令
SELECT u.id,
jmeno,
email
FROM friends f
INNER JOIN login u
ON f.idfriend = u.id
WHERE f.iduser = 44
AND u.online =1
但我意识到这不是正确的解决方案,因为当用户44和用户10想成为朋友时,必须有两种关系:
44 - 10
10 - 44
我只想从数据库中的一行中选择关系 所以在iduser和idfriend中找到id。现在我在这里使用这种单向关系sql。
答案 0 :(得分:0)
有很多方法可以做到这一点。一种是在联接中进行or
,以便您加入iduser
或idfriend
:
select
u.*
from
login u
join friends f
on (u.id = f.iduser
and f.idfriend = 44)
or (u.id = idfriend
and f.iduser = 44)
where
u.id != 44;
另一种方法是创建一个子查询,创建所有双向朋友关系列表,然后从中进行选择:
select
*
from
(select
iduser,
u.*
from
friends f
inner join login u on f.idfriend = u.id
union
select
idfriend,
u.*
from
friends f
inner join login u on f.iduser = u.id) q
where
q.iduser = 44
and q.isonline = 1
您没有指定使用哪个数据库引擎 - 如果您使用的是支持CTE的数据库(例如Oracle或SQL Server),则子查询可以在CTE中完成。
第二种方法占用资源更多,但只需要对代码进行一次更改即可选择不同的ID。
所有三个查询都在此SQLFiddle中,但我删除了现有的双向友谊以说明逻辑。
答案 1 :(得分:0)
您当前的架构不一定是坏事。这就是我设计这种关系的方式。
Friends表是标准的交叉引用表。如果朋友关系被切断,你需要清理双方,但这很容易。它允许您加入一列id
,并立即获得正确的idfriend
。它也使得容易约束以保证唯一性。
你当前的架构也允许(10,44)意味着10想要成为44的朋友,但如果(44,10)不存在,那么也许44不想成为10的朋友。但是那么也许那样不是业务要求。
如果您希望(10,44)等同于(44,10),那么在创建关系时,您将不得不添加一个额外的查询以查看双方并确保现有关系不存在。
您可以在join子句中使用OR
或使用UNION执行此操作。 Joe的代码对我来说很好看。您也可以在此处查看视图(或索引视图)。