不使用php的高效sql查询

不使用php的高效sql查询,php,mysql,sql,Php,Mysql,Sql,我有一个members表,其中每个站点成员都是唯一的id。 乙二醇 第二个表是具有以下结构的friends表 id meid friendid date 我将使用什么查询来获取特定用户基于共同好友的好友建议并进行相应排序。在我使用php来循环访问和收集共同的朋友之前,随着网站的发展,php开始出现问题并耗尽内存 这是我正在使用的函数 //----------------------------------------------- function getFriendSu

我有一个members表,其中每个站点成员都是唯一的id。 乙二醇

第二个表是具有以下结构的friends表

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;
}
/--------------------------------------------------------------
函数getFriendSuggestions($id)
{
$friendids=getFriendArray($id);//返回您的朋友列表
$networkids=getNetworkIdArray($id);//返回网络中所有成员(朋友及其朋友)的列表
$diff=array_merge(array(),array_diff($networkids,$friendids));
$diff_mutual=array();
$diff_mutual_total=数组();
对于($n=0;$n$value)
{
$d[]=$diff[$key];
$dm[]=$diff_mutual[$key];
}
$cv=数组($d,$dm);
返回$cv;
}
你想要“我朋友的朋友,但不是我朋友的朋友”


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

(B, someguy) (someguy, A)
在数据库中,没有(B,A)条目

我们知道用户A的ID,并将其作为辅助。然后我们可以做:

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;

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

我猜这是基于共同的朋友。你能发布表格结构吗?朋友的建议基于第二个朋友圈,意思是朋友的朋友。因此,你需要选择所有这些朋友,然后检查他们与当前成员的相互好友数。是的,这就是我在上面发布的功能。问题是,当网络变大时,它是无效的。这让我,他们的朋友们,感到困惑。它可以修改为使用朋友吗table@SirLojik-我使用朋友表三次。每次我给它取个新名字。我第一次称它为
my_friends
,因为它是与
members
表中的行相关的朋友列表。下次它与他们的朋友,而不是我的朋友相关时,我将其别名为
他们的朋友
。它是同一个表,但使用了多次,所以给出了不同的别名。实际上,您的查询中有一个错误。左连接的“ON”子句是错误的。正确的答案是:关于“有我的朋友”。meid=me.id和“有我的朋友”。friendid=他们的朋友
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;