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'
Related
I have 2 tables:
Friends
ID | Profile | Check
------+-----------+---------
int | int | bool
Where ID is person who sent original friend request, Profile is ID of person request was sent to, and Check is 0 = request pending; 1 = request accepted.
Messages
OwnerID | ...
-----------+-------
int | ...
Where OwnerID is ID of member who wrote the message.
So basically, what I am looking at is first:
select all rows from friends_list table where ID or Profile is equal to the memberID cookie. BUT heres my plight: If I send another user a friend request, then my ID is placed in the ID field and their ID is placed in the Profile field of the friend_list table. But if another user requests a friend request from me, then my ID would go into the Profile field and theirs would go in the ID field.
So, I would have a row where ID = 1, and Profile = 2. And the next row would be ID = 3 and Profile = 1. Now, both users with IDs 2 and 3 are friends of mine (ID 1), So I need to show all messages from 1, 2, and 3 (mine and my two friends) where check = 1
I think what you want is this:
(
SELECT m.*
FROM Messages m
INNER JOIN Friends f ON m.OwnerID = f.ID
WHERE f.Profile = ?
) UNION (
SELECT m.*
FROM Messages m
INNER JOIN Friends f ON m.OwnerID = f.Profile
WHERE f.ID = ?
)
You need to look at this a two separate queries, I don't think you can sensibly do this with just a combination of JOINs.
Assuming you are using MySQL, this should not return duplicate rows, because the default modifier for UNION is DISTINCT. Other RDBMS engines may require you to explicitly state this or use some other work-around (for example a GROUP BY on the actual message ID).
You may also want to add an m.Check = 1 condition to the WHERE clause of both queries, to ensure you only get messages where the friend request has been accepted.
Obviously the above is designed to be used as a prepared statement, where both placeholders would be substituted with the same data - the memberID cookie.
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.
I am working on a twitter clone in PHP for school, and I have one major problem. I cannot find a way to implement a follower system. There is a table for users, and I want to add a field that holds the ids of all of the users that each user follows.
Should I separate the ids with commas and then split them apart in PHP? And then I need to select all of the tweets from the tweets table that were tweeted by any of the users followers. Is there an SQL command that I can use? Something similar to
SELECT *
FROM tweets
WHERE author='$followeduser'"
but where $followeduser is multiple ids.
Have a USER_MASTER table like this
USER_ID (int)
USER_NAME(varchar(50))
Create a table called USER_FOLLOWERS like this
USER_FOLLOWER_ID // Auto increment-Primary Key for this record
USER_ID (int) // foriegn key to UserId column in USER_MASTER table
FOLLOWER_ID (int) // foriegn key to UserId column in USER_MASTER table
Store the UserId in the first column and store the UserId of the User who follows this user in the Follower_ID column.
So your data will look like this
USER_ID USER_NAME
--------------------------------------
1 SCOTT
2 JARED
3 MARC
4 ERIC
USER_FOLLOWER_ID USER_ID FOLLOWER_ID
--------------------------------------
1 1 2
2 1 3
3 1 4
4 2 1
So this means , The User Scott has 3 followers, Jared, Marc and Eric. User JARED HAS one Follower, that is SCOTT
To get the list of Followers for a user(ex : Scott (ID=1)) , you can do a Join between these 2 tables
SELECT U. USER_ID, U.USER_NAME From USER_MASTER U
INNER JOIN USER_FOLLOWERS UF ON U.USER_ID=UF.FOLLOWER_ID
WHERE UF.USER_ID=1 // 1 is the ID of SCott
Make a join table.
Putting all IDs in a list is not the normalized way and can lead to many many issues.
Have a relations table where you have one column called user and second that is following. So if user 1 is following user 3 and 5, then you would have an entree where user = 1 following = 3 and user = 1 following = 5 (use whatever ID's you want). You also have your Tweets Table where you store all tweets. Youre going to want to make a query that joins the two tables
I am making an autosuggesting function, when the user writes something in the field it stores it in:
$queryString = $db->real_escape_string($_POST['queryString']);
I want it to autosuggest after the users friends. The user´s friends is in users_friends, but only the friend´s ID. Now their full_name is in the table "users". And i want when you search it should in users for the full_name + check if its friends with the user.
As you may understand i do not expect all my users to know eachother id´s so writing e.g "52" "233", but searching for their full_name s.
UPDATE:
I know tried doing this:
$query = $db->query("SELECT uf.bID
FROM users friends, users_friends uf
WHERE uf.uID = '1' AND uf.type = 'friend' AND friends.full_name LIKE '$queryString%' LIMIT 10;"
);
It selects the bID, from the users friends WHERE the userid is 1 and are friend.
Now i start to see some results i think. When i write a full_name that im friends with, i get the id of the user(the id that is stored in bID). Now i just need to grab the full_name in "users" where id = bID..
table: users
id | full_name
table: users_friends
id | uID | bID
So conclusion of all this (trying to make a better summary in order to make you understand better: )
When you type in e.g Jack in the search field, then the $queryString is now "jack". Then it is taking "Jack"(full_name in users), grabbing his id(id in users), if he exists there ofcourse, and then match it with bID (in users_friends) where uID is $USER; ($user is the current user that are logged in´s id.)
Hope this was easier to understand, please leave comment if theres something unclear.
So, as i figure it out, you've got the current user's id in $USER and its query string in $queryString, and what you want is the names of the user's friends based on the $queryString, am I right?
So, assuming the database's schema is as you've put:
table: users
id | full_name
table: users_friends
id | uID | bID
See if this query works out for you, then:
SELECT users.full_name
FROM users INNER JOIN users_friends ON users.id=users_friends.uID
WHERE bID=$USER AND users.full_name LIKE '$queryString%'
LIMIT 10;
Where $USER and $queryString are your variables.
Do you want to read data from many tables at once??
SELECT table1.id, table2.name FROM table1, table2 WHERE ...
My english is not very good to understand everything :D
I didn't understood your question
But you can use this query:
mysql_query("SELECT * FROM table_one, table_two WHERE table_one.id = table_two.id");
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