我正在建立一个饲料系统ala facebook只是为了它的乐趣和训练,但我提出了一个有趣的问题。想象一下这种情况:
我是nr1,nr2和nr3的朋友。在我的数据库中,它也是数据库中的用户,nr4,我不是他的朋友。所以,请说nr1 befriend nr4,在这种情况下,我希望我的feed更新nr1是nr4的朋友。这基本上不是很难做到(至少要让它起作用,我不会对性能有所了解:P)。 然后nr1与nr2成为朋友,但这与nr2 befriend nr1相当,这就是我的问题。
我的友谊数据库以一个友谊生成两个记录的方式工作。我读过这通常是更快的方法。
友谊表:
用户表:
我想出了以下代码:
SELECT
u1.user_id AS friend_id,
u1.user_name SA friend_name,
u2.user_id AS friends_friend_id,
u2.user_name AS friends_friend_name
FROM users AS u1
JOIN friendship AS f1
ON u1.user_id = f1.friend_id
&& f1.user_id = {$user_id}
&& f1.friend_pending = 0
JOIN friendship AS f2
ON u1.user_id = f2.user_id
&& f2.friend_pending = 0
JOIN users AS u2
ON f2.friend_id = u2.user_id
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;
Okey这基本上做的是它让我所有的朋友与我上次登录后与其他人交朋友。唯一的问题是,如果我是两个相互交朋友的朋友,将在此查询中选择他们两个。 差异(这使得无法使用SELECT DISTINCT)是这样的;
第一次nr1将成为朋友而nr 2将成为朋友的朋友
第二次nr2将成为朋友而nr1将成为朋友的朋友。
我不希望这样,我希望每个关系有一行。
你们有任何想法如何解决这个问题?我提出的任何解决方案都没有显示任何内容:(
谢谢!
第一次编辑:我刚刚提出了另一个与此问题相关的问题。在phpMyAdmin中,上面生成了一个包含4列的正确表。但是在php(或者更确切地说是codeigniter的查询函数)中,它只显示了两列,但是添加了更多的行...这最终我不知道谁是谁...
再次第二次编辑:Okey我刚刚解决了我在第一次编辑中提出的问题,我只是用AS重命名了这些列。你仍然有主要问题。
第3次修改:Stevie G正在请求一些示例数据,这是查询结果:
friend_id | friend_name | friends_friend_id | friends_friend_name
1 nr1 4 nr4
1 nr1 2 nr2
2 nr1 1 nr2
如果你关注我的小故事,这就是我得到的。 id = 1不是“我”,而是另一个用户
第4次修改不幸的是,我觉得我还不够清楚。我最想得到的是一个数组,其中每个元素包含:
就像编辑3中的示例数据一样,除了我之前的名字可能会误导你... 所以我的问题是,正如你可以看到编辑3,如果我的两个朋友成为朋友,我会得到两行为一个关系。我想得到的是:
friend_id | friend_name | friends_friend_id | friends_friend_name
1 nr1 2 nr2
2 nr1 1 nr2
我希望自己更清楚!感谢
答案 0 :(得分:0)
所以对我而言,看起来你的要求是不完整的,因为在朋友提要中,如果nr2和nr1相互交朋友,你想要:
情景#1
如果您的朋友的朋友也在您的朋友中,您需要另一个联接检查,如果是,则返回名为AlsoMyFriend的布尔列。然后,如果也是友谊朋友是1,则返回“你的共同朋友彼此友好”,否则返回正常的“你的朋友会成为新朋友。”
或者,您可以在代码中执行此操作,只需检查朋友的朋友ID是否在朋友的ID列表中,然后根据该ID翻转您的Feed语句。
情景#2
在友谊表* primary_mover *中添加一列,并将该值设置为启动友谊的* user_id *。在查找朋友的朋友时,可以过滤*,其中primary_mover = user_id *仅获得1个双边关系。
作为一个简单的衡量标准,你可以简单地添加一个过滤器,只说朋友的朋友ID大于朋友的ID:
SELECT
u1.user_id AS friend_id,
u1.user_name SA friend_name,
u2.user_id AS friends_friend_id,
u2.user_name AS friends_friend_name
FROM users AS u1
JOIN friendship AS f1
ON u1.user_id = f1.friend_id
&& f1.user_id = {$user_id}
&& f1.friend_pending = 0
JOIN friendship AS f2
ON u1.user_id = f2.user_id
&& f2.friend_pending = 0
&& f2.friend_id > f2.user_id -- pulls nr1 befriending nr2, not nr2 befriending nr1
JOIN users AS u2
ON f2.friend_id = u2.user_id
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;
答案 1 :(得分:-1)
您尝试使用
吗?SELECT DISTINCT
答案 2 :(得分:-2)
这是一个棘手的问题,但是,试试这个:
SELECT --Select your user details, and your direct friends details
u1.user_id UserId,
u1.user_name UserName,
u2.user_id FriendsUserId,
u2.user_name FriendsUserName
FROM users AS u1
JOIN friendship AS f1
ON u1.user_id = {$user_id}
&& f1.friend_pending = 0
JOIN users AS u2
ON f1.friend_id = u2.user_id
JOIN friendship AS f2
ON f1.friend_id = f2.userid
&& f2.friend_pending = 0
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;
UNION
SELECT --Select your user details, and your friends friends details
u3.user_id UserId,
u3.user_name UserName,
u4.user_id FriendsUserId,
u4.user_name FriendsUserName
FROM users AS u3
JOIN friendship AS f3
ON u3.user_id = {$user_id}
&& f3.friend_pending = 0
JOIN friendship AS f4
ON f3.friend_id = f4.user_id
&& f4.friend_pending = 0
JOIN users AS u4
ON f3.friend_id = u4.user_id
WHERE TIMESTAMPDIFF(SECOND, f4.lastchange, '{$last_login}' ) < 0;
假设结果与我认为的结果一样,UNION应该过滤掉dupes,因为u1.user_id应该始终是你的user_id ..
答案 3 :(得分:-2)
尝试
SELECT
u1.user_id AS friend_id,
u1.user_name SA friend_name,
u2.user_id AS friends_friend_id,
u2.user_name AS friends_friend_name
FROM users AS u1
JOIN friendship AS f1
ON u1.user_id = f1.friend_id
&& f1.user_id = {$user_id}
&& f1.friend_pending = 0
JOIN friendship AS f2
ON u1.user_id = f2.user_id
&& f1.user_id <> f2.friend_id
&& f2.friend_pending = 0
JOIN users AS u2
ON f2.friend_id = u2.user_id
WHERE TIMESTAMPDIFF(SECOND, f2.lastchange, '{$last_login}' ) < 0;