2

すべてのサイト メンバーが一意の ID であるメンバー テーブルがあります。例えば

id  firstname   secondname  emailaddress    country city    gender  

2 番目のテーブルは、次の構造を持つフレンズ テーブルです。

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 に答える