2

我有一个成员表,其中每个站点成员都是唯一的 ID。例如

id  firstname   secondname  emailaddress    country city    gender  

第二个表是朋友表,结构如下

id  meid    friendid    date

我将使用什么查询来根据共同的朋友获取特定用户的朋友建议并进行相应的排序。在我使用 php 循环并收集共同的朋友之前,但随着网站的增长,php 开始出现异常并耗尽内存。

这是我正在使用的功能

//-----------------------------------------------    
function getFriendSuggestions($id)    
{
            $friendids=getFriendIdArray($id);  //returns list of your friends
            $networkids=getNetworkIdArray($id);//returns list of all members in your network(friends and their friends)
            $diff=array_merge(array(),array_diff($networkids,$friendids));
            $diff_mutual=array();
            $diff_mutual_total=array();
            for ($n=0;$n<count($diff);$n++)
            {
                $ff=getFriendIdArray($diff[$n]);
                $mf=array_merge(array(),array_intersect($ff,$friendids));
                $diff_mutual[]=$mf;
                $diff_mutual_total[]=count($mf);
            }
            $diff=array_merge(array(),$diff);
            $diff_mutual=array_merge(array(),$diff_mutual);
            $diff_mutual_total=array_merge(array(),$diff_mutual_total);    
            $w=$diff_mutual_total;
            arsort($w);
            $d=array();
            $dm=array();
            foreach ($w as $key => $value)
            {
                $d[]=$diff[$key];
                $dm[]=$diff_mutual[$key];
            }
            $cv=array($d,$dm);
            return $cv;
}
4

2 回答 2

3

如果有大量此类条目,我们说 B 可能是 A 的朋友

(B, someguy) (someguy, A)

在数据库中,并且没有(B,A)条目。

我们知道用户 A 的 ID 并将其设为 AID。然后我们可以这样做:

SELECT b.meid, COUNT(b.meid) AS incommon
FROM friends AS b
JOIN friends AS a ON (b.friendid = a.meid AND a.friendid = AID)
GROUP BY b.meid ORDER BY incommon DESC;

这将告诉我们 A 的所有“可能的朋友”,包括那些已经是 A 朋友的人。然后我们必须排除它们:

SELECT maybe.meid, maybe.incommon FROM
( SELECT b.meid, COUNT(b.meid) AS incommon
FROM friends AS b
JOIN friends AS a ON (b.friendid = a.meid AND a.friendid = AID)
GROUP BY b.meid ORDER BY incommon DESC ) AS maybe
LEFT JOIN friends AS already ON (maybe.friendid = already.meid AND already.friendid = AID) WHERE already.friendid IS NULL;

然后我们需要填充其余的字段:

SELECT members.firstname, members.secondname, maybe.incommon FROM
( SELECT b.meid, COUNT(b.meid) AS incommon
FROM friends AS b
JOIN friends AS a ON (b.friendid = a.meid AND a.friendid = AID)
GROUP BY b.meid ORDER BY incommon DESC ) AS maybe
LEFT JOIN friends AS already ON (maybe.friendid = already.meid AND already.friendid = AID) 
    JOIN members ON (members.id = maybe.meid)
    WHERE already.friendid IS NULL;

这将返回 AID 的朋友建议,包括每个选择有多少共同点(例如“John Doe(15 个共同朋友)”等)。

于 2012-10-16T13:27:13.377 回答
2

你想要“我朋友的朋友,但不是我的朋友”

SELECT
  me.id                               AS member_id,
  their_friends.friendid              AS suggested_friend_id,
  COUNT(*)                            AS friends_in_common
FROM
  members        AS me
INNER JOIN
  friends_map    AS my_friends
    ON my_friends.meid = me.id
INNER JOIN
  friends_map    AS their_friends
    ON their_friends.meid = my_friends.friendid
LEFT JOIN
  friends_map    AS friends_with_me
    ON  friends_with_me.meid     = their_friends.friendid
    AND friends_with_me.friendid = me.id
WHERE
  friends_with_me.meid IS NULL
GROUP BY
  me.id,
  their_friends.friendid
于 2012-10-16T13:25:36.247 回答