php friend system, display friends of my friends - php

I have a table named friends, keeps my friends in a php friend system. The table is as follows:
friend_id | user_one | user_two
My script is the following for displaying my friends.
$check_friend_query = mysql_query(" SELECT friends_id from friends WHERE (user_one='$session_user_id' AND user_two ='$user_id') OR (user_one='$user_id' AND user_two='$session_user_id') ");
if( mysql_num_rows($check_friend_query) == 1 ){
echo" 1st degree friend";
}
All I want is to display 2nd degree friends. My 2nd degree friends are the friends of my friends. Any idea how to do this?

You can run an original query to grab all of your friends (like you have), then another to find their friends using their user ID as the variable to look for.
mysql_query("SELECT friends_id from friends WHERE user_one='$user_id'");
Something like this would check friends_id for all friends where the name is the user_id of the person.
Although the variables are a bit difficult to figure out, since I don't know the script.

Join the friends against itself:
SELECT degree2.*
FROM friends
LEFT JOIN friends AS degree2 ON friends.user_two = degree2.user_one
WHERE friends.user_one = 'original friend';
For further degrees, you'd just add another join level, e.g.
LEFT JOIN friends AS degree3 ON degree2.user_two = degree3.user_one
LEFT JOIN friends AS degree4 on degree3.user_two = degree4.user_ond
etc...

Related

PHP MySQL Search for users by mutual friends and country

I am developing a sort of social network of sorts. Today I started making a dynamic search bar with AJAX and php. In in I have a query that searches for users in a "users" table. I would like to order my search results by relevance, if you know what I mean. Like for instance if I have user with id 3, searching for John, I would like to order the results by the number of mutual friends, and possibly where the person is living.
My tables look like this
Users
id| name | country
Friends
id|user_id|friend_id
the queries I have for the moment are
SELECT * FROM users WHERE name LIKE $keyword
for user searching
and
SELECT COUNT(*) as mutual from users where id in
(select friend_id from friends where user_id = 3 and friend_id in
(select friend_id from friends where user_id = 7)
This for instance will return the number of mutual friends between user 3 and user 7.
How can I combine the two, in order to give more relevant search results?
Thank you in advance!
Like for instance if I have user with id 3, searching for John, I
would like to order the results by the number of mutual friends
Find friends of my friends whos name contains 'john' order by number of mutual friends:
select u.*, count(f1.user_id) as num_mutual_friends
from friends f1 -- my friend
join friends f2 on f2.user_id = f1.friend_id -- friend of my friend
join users u on u.id = f2.friend_id
where f1.user_id = 3
and u.name like '%john%'
and u.id <> 3
group by u.id
order by num_mutual_friends desc;
Show users from US first:
order by (u.country = 'us') desc, num_mutual_friends desc;
http://sqlfiddle.com/#!9/728c8a/3

MySQL Foreign Keys.. confused

I am trying to understand MySQL Foreign Keys, I hope someone can help.
I have two tables with the following structures;
reports
+-----------+------+-----------+------------------+
|id|user_id |status|report_type|request_id |
+-----------+------+-----------+------------------+
| |
+-------------------------------------------------+
users
+-----------+------+-----------+------------------+
|id|username|f_name|l_name |email |
+-----------+------+-----------+------------------+
| |
+-------------------------------------------------+
I have a foreign key in the reprots table (fk_uid) that links the user_id column in the reports table to the id in the users table.
I want to run a MySQL Query in PHP that will pull all the reports for a given user (either by username or user_id, not sure which is best?)
Thanks!
It could be done by simple inner join as
select
users.username,
users.f_name,
users.l_name ,
reports.status,reports.report_type,
reports.request_id from reports
inner join users on users.id = reports.user_id
If you want to search for a specific user then use where condition as
select
users.username,
users.f_name,
users.l_name ,
reports.status,
reports.report_type,
reports.request_id from reports
inner join users on users.id = reports.user_id
where users.username = 'some user name'
And if you want by userid then where condition is
where users.id = 'your user id'
if you only want to get reports and no user information then you can do a direct query to reports table if you have a user_id
Suppose you have userid in a variable in $userid
like
select * from reports where user_id = $userid
if you want data from both tables then you need to do a join like this
Reports for a specific user:
select r.*, u.* from reports r, users u where r.user_id = $userid
and r.user_id = u.id
Reports for all users
select r.*, u.* from reports r, users u where r.user_id = u.id
if you want to learn more about joins the visit this link
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
http://www.sitepoint.com/understanding-sql-joins-mysql-database/

Follow friend of friends suggestion MySQL

I'm creating a 'Follow Suggestion' feature, where I'd like to show random Friends of my Friends who's NOT my friend.
user_friends table
friend_id | friend_one | friend_two | role
user table
uiD | username
For each friend that a user follow it makes two records. If user 1 and 2 become friends a record would be created where, friend_one = 1 & friend_two = 2, friend_id = ramdom AUTO_INCREMENT number role = fri in the user_friends table.
User table, just has the users id and username.
How would I make a sql query that suggests "who to follow" based on friends of my friends ? Just how twitter does it.
What I've tried hasn't quite worked which does not seem to make much sense even to me.
http://pastebin.com/tCt6jdAZ <- Query code. ( Don't want to post here because feels useless ).
If I understand your question correct:
you need to join your 'user_friends' table twice:
select * from
user_friends level1,
user_friends level2
where
level1.friend_two = level2.friend_one -- or opposite i am not sure if a understood your model
and level1.friend_one = 'starting friend id'

Get mutual friends from Facebook friends (MySQL table)

I'm trying to get mutual friends between 2 people.
I've saved the persons friends in a table called "friends" with the following fields:
id | facebook_id | name | uid | timestamp
id = unique id for the record
facebook_id = the friends facebook id
name = the friends name
uid = the users uid on my site, which is a friend to the person saved in the table
timestamp = don't need to explain :-)
Hope it make sense, have tried various ways to get the friends, but without luck
I dont know if using subqueries would be faster or mySQL already optimizes it.
Solution with subqueries:
SELECT f1.id, f1.name
FROM (SELECT id, name FROM friends WHERE uid=1) f1
JOIN (SELECT id, name FROM friends WHERE uid=2) f2
ON f1.id=f2.id;
It would be nice if MySQL has an INTERSECT operator, but...
You can grab all the friends of one person:
SELECT id, name
FROM friends
WHERE uid = 1
You could then JOIN this list back to the friends table, looking for the same friend for the other user:
SELECT f1.id, f1.name
FROM friends f1
JOIN friends f2 on f1.id = f2.id
WHERE f1.uid = 1
and f2.uid = 2
It's pseudo-code, but it should be close.

Friend of a friend in PHP/MySQL?

I have a social network similar to myspace/facebook. In my code you are either a person's friend or not a friend, so I show all actions from people you are friends with (in this post I will refer to actions as bulletin posts alone to make it easier to visualize.
So you every time a person post a bulletin it will show up to any person who is there friend.
In mysql you would get a persons friend list by doing something like this,
SELECT user_id FROM friends WHERE friend_id = 1 (user ID)
I want to know how a site like facebook and some others would show all bulletin post from your friends and from your friends' friends?
If anyone has an idea please show some code like what kind of mysql query?
The answer is that they aren't doing selects on a friend table, they are most likely using a de-normalized news-event table. We implemented a news-feed similar to Facebooks on DoInk.com, here's how we did it:
There is the notion of a "NewsEvent" it has a type, an initiator (a user id) and a target user (also a user id). (You can also have additional column(s) for other properties relevant to the event, or join them in)
When a user posts something on another users wall we generate an event like this:
INSERT INTO events VALUES (wall_post_event, user1, user1)
When viewing user1's profile, you'd select for all events where user1 is either the initiator or the target. That is how you display the profile feed. (You can get fancy and filter out events depending on your privacy model. You may consider doing this in memory for performance reasons)
Example:
SELECT * FROM events WHERE initiator = user1 or target = user1 //to see their profile feed
SELECT * FROM events WHERE initiator IN (your set of friend ids) //to see your newsfeed
When you want to see the newsfeed for all events relative to your friends you might do a query selecting for all events where the initiator is in your set of friends.
Avoid implementations with sub-selects, depending on the complexity, they will not scale.
you do a subquery:
SELECT DISTINCT user_id FROM friends WHERE friend_id IN
(SELECT user_id FROM friends WHERE friend_id = 1)
Test both of these for performance:
SELECT DISTINCT user_id
FROM friends f1
JOIN friends f2 ON f1.friend_id = f2.user_id
WHERE f2.friend_id = 1
and
SELECT DISTINCT user_id
FROM friends
WHERE friend_id IN (SELECT user_id FROM friends WHERE friend_id = 1)
Often they're the same but sometimes they're not.
Make sure friend_id and user_id are indexed.
The simple approach would be to do some kind of simple nested clause. So say you have a table with posts and the posters id, and a friends table, the first layer would be
SELECT post FROM posts JOIN friends
on post.userid = friends.friend_id
WHERE friend.id = 1 (user ID)
then to get a friends of friends
SELECT post FROM posts JOIN
(SELECT DISTINCT friends_2.friend_id FROM friends AS friends_1
JOIN friends as friends_2
on friends_1.friend_id = friends_2.id where friends_1.id = 1)
AS friends
wHERE post.userid = friends.friend_id AND mainid = 1 (user ID)
You can repeat this nesting each time you want to add another layer of friend abstraction. The problem with this approach is that it would take a very long time to execute. For every time you add a layer of friend abstraction you are increasing the complexity by a power of n (where n is the number of rows in your table).
It is more likely that they are saving the viewable friends in a table somewhere, so lets make a new tabled called friends_web
user_id, friend_id, level
when a user friends someone, it adds that new friend into friends_web at a level of 0(since that friend is no people away) then adds that friends friends at a level of 1 (since its 1 friend away). In order to keep the table integrity you would also want to add the inverted record. To clarify if A adds B as a friend and C is a friend of B, the following two records would get added to our new table
A, C, 1
C, A, 1
since now A can see C and C can see A.
now when we want a query we just do
SELECT post FROM posts
JOIN friends_web ON post.user_id = friends_web.friend_id
WHERE friends_web.user_id = user_id AND friends_web.level < 2 (or however deep you want to look)
by doing that you minimized your query complexity when doing post lookups while being able to look more then 1 layer deep into a friend web.
Sorry for the long winded response.
This should pull out all the user's friend's posts.
SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1) ORDER BY post_id DESC
This should pull out all posts that are your friend's friend's.
SELECT * FROM posts WHERE uid IN (SELECT friend_uid FROM friends WHERE uid IN (SELECT friend_uid FROM friends WHERE uid=1)) ORDER BY post_id DESC

Categories