简体   繁体   English

改善朋友列表查询:统计共同的朋友

[英]improving a friends list query : counting the mutual friends

i have two tables in my database one is to keep users info (users_table ) and the other one keeps track of the friends 我的数据库中有两个表,一个用于保存用户信息(users_table),另一个用于跟踪朋友

users_table: users_table:

id    username      avatar  
1         max       max.jpg  
2         jack      jack.jpg  

friends_table : friends_table:

id    u1_id      u2_id  
1         1          2  
2         1          3  

in every user profile i show his/her friends list 在每个用户个人资料中,我显示他/她的朋友列表

here is my query 这是我的查询

select u.id,
    u.username,
    u.avatar
from friends_table f
join users_table u on f.u1_id = u.id || f.u2_id = u.id
where u.id <> $profile_id
    and (f.u1_id = $profile_id || f.u2_id = $profile_id)

this query selects friends of the profile owner ($profile_id) 此查询选择个人资料所有者的朋友($ profile_id)

and join them with the user table to get each friend username and avatar 并使用用户表加入它们以获取每个朋友的用户名和头像

now i want to count the mutual friends between each friend and the profile owner is it possible to this in one query or should i do some long and probably slow query like this for each founded friend( it's just a example and it might have some syntax error ): 现在我想要计算每个朋友和个人资料所有者之间的共同朋友是否可以在一个查询中进行此操作,或者我应该为每个成立的朋友做一些长而且可能很慢的查询(这只是一个示例,它可能有一些语法错误):

       foreach ( $friends_list_query_resul as $qr ){
       $friend_id = $qr['id'];

       $mutual_count = mysql_query
    ( "select count(*) from friends_table where 
    ($u1_id = $friend_id || $u2_id = $friend_id )
               && 


    ( $u1_id IN ( SELECT `u1_id`,`u2_id` from friends_table where
     ($u1_id = $profile_id || $u2_id = $profile_id ) )

||

      $u2_id IN ( SELECT `u1_id`,`u2_id` from friends_table where
     ($u1_id = $profile_id || $u2_id = $profile_id ) )


       ")
        }

Your first query could also be written as: 您的第一个查询也可以写成:

select distinct u.id,
        u.username,
        u.avatar
    from users_table u where u.id in 
        (select case when u1_id=$profile_id then u2_id else u1_id end 
        from friends_table f where case when u1_id=$profile_id 
        then u1_id else u2_id end =$profile_id);

The mutual friends query can be written as a single query in similar fashion: 共同的朋友查询可以以类似的方式编写为单个查询:

select u.id, (select count(f.id) from friends f where 
    case when f.u1_id=u.id then u2_id else u1_id end in 
        (select distinct case when u1_id=$profile_id then u2_id else u1_id end 
        from friends where case when u1_id=$profile_id then u1_id else u2_id 
        end =$profile_id) 
    and u1_id=u.id or u2_id=u.id and 
    (u1_id <> $profile_id and u2_id <> $profile_id)) 
as mutual_frnds from user u where u.id <> $profile_id;

but you might want to performance test either of them before using. 但您可能希望在使用前对其中任何一个进行性能测试。

All you need is one query: 您只需要一个查询:

select id, username, avatar, -- ...
(
  select count(*)
  from friends_table f1
  inner join friends_table f2 on f1.u2_id = f2.u1_id and f2.u2_id = f1.u1_id
  where f1.u1_id = users_table.id
)
as mutual_friend_count
from users_table

The meaning of the subquery is: 子查询的含义是:

Give me the count of the "friend of a friend" relations the user participates in, such that the target of the first friend relation is the source of the second friend relation, and the target of the second friend relation is the source of the first one. 给我用户参与的“朋友的朋友”关系的计数,使得第一朋友关系的目标是第二朋友关系的源,并且第二朋友关系的目标是第一朋友关系的源。一。

First, I do not understand why so complicated query to retrieve the user's friends... It should be simply achieved by this query: 首先,我不明白为什么如此复杂的查询来检索用户的朋友...应该通过这个查询简单地实现:

select u.id,
    u.username,
    u.avatar
from friends_table f
left join users_table u on f.u2_id = u.id
where f.u1_id = $profile_id

Explain: the logged in user is the one whose id is the same as f.u1_id . 说明:登录用户是id与f.u1_id相同的f.u1_id Therefore we only select friends whose ids are in f.u2_id . 因此,我们只选择id为f.u2_id朋友。

Then, to count the mutual friends of my friends we can use query like this: 然后,为了统计我朋友的共同朋友,我们可以使用这样的查询:

select count(*) as mutual_count, f.u1_id as mutual_friend_id
from friends_table f
where f.u1_id IN (select f.u2_id from friends_table where f.u1_id = {$profile_id})

where $profile_id is the ID of logged in user... 其中$ profile_id是登录用户的ID ...

Is this correct? 它是否正确?

i've decided to add two rows for each friend relation to the table . 我决定为表中的每个朋友关系添加两行。

id    u1_id      u2_id  
1         10         20  
2         20         10

it makes the process easier and faster . 它使过程更容易,更快捷。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM