I just want to get the result of a single user's friends and for each friend to join the last timestamp of the chat between the user and the friend:
User friends list:
Friend1: fname, lname,...., chat timestamp
Friend2: fname, lname,...., chat timestamp
...
users table is the main user information table:
usr_id,usr_fname,usr_lname
friends table is a table containing the friendships:
frd_id, frd_usr_id1, frd_usr_id2
chats table is a table containing chats between users:
cht_id, cht_usr_id1,cht_usr_id2,cht_timestamp
Can anyone help me with SQL statements?
Let say that the requesting user ID is in $user_id variable
Try this, it should work...
SELECT u1.usr_fname [Friend1First],
u1.usr_lname [Friend1Last],
u2.usr_fname [Friend2First],
u2.usr_lname [Friend2Last],
MAX(ch.cht_timestamp) [LastChatTime]
FROM Chats ch
JOIN users u1 ON ch.cht_usr_id1 = u1.usr_id
JOIN users u2 ON ch.cht_usr_id2 = u2.usr_id
WHERE EXISTS (SELECT frd_id from friends fs WHERE (fs.frd_usr_id1 = a.usr_id AND fs.frd_usr_id2 = b.usr_id)
OR (fs.frd_usr_id2 = a.usr_id AND fs.frd_usr_id1 = b.usr_id))
GROUP BY u1.usr_fname, u1.usr_lname, u2.usr_fname, u2.usr_lname,
This is the answer:
SELECT f.frd_id, u.usr_id, u.usr_fname, u.usr_lname, MAX(c.cht_timestamp)
FROM friends AS f
LEFT JOIN users AS u ON u.usr_id IN (
SELECT u1.usr_id FROM users AS u1 WHERE u1.usr_id != $user_id)
LEFT JOIN chats AS c ON ( (c.cht_usr_id1=$user_id AND c.cht_usr_id2=u.usr_id) OR
(c.cht_usr_id1=u.usr_id AND c.cht_usr_id2=$user_id) )
WHERE ( (f.frd_usr_id1=$user_id AND f.frd_usr_id2=u.usr_id) OR
(f.frd_usr_id1=u.usr_id AND f.frd_usr_id2=$user_id) )
GROUP BY u.usr_id ORDER BY MAX(c.cht_timestamp) DESC
Related
I have tables:
likes - id, user_id, like_user_id<br>
users - id, name, email ...,<br>
friends - id, user_id, friend_id, status<br>
Is it possible to sort it with one SQL query first to show the friends then the other users.
Any help would be appreciated.
Thank you.
I tried this and it works, but the problem is it give me double results of users:
select *
from `likes`
left join `users` on `users.id` = `likes.user_id`
left join `friends` on `friends.user_id` = `likes.user_id`
or `friends.friend_id` = `likes.user_id`
where `likes.id` = 1
order by `friends.user_id` = 5
or `friends.friend_id` = 5
You need to work with a UNION here to merge the liked users with the befriended users. Upon doing this, you can create an artificial column friend, that you fill with 1 in the friend query and 0 in the like query. Later on you can order by that column.
SELECT
friends.user_id,
1 as friend,
users.*
FROM
friends
JOIN users ON users.id = friends.friend_user_id
UNION SELECT
likes.user_id,
0 as friend,
users_liked.*
FROM
likes
JOIN users as users_liked ON likes.like_user_id = users_liked.id
WHERE
user_id = '$userId'
ORDER BY friend DESC, id ASC
This will return a list of all friends, followed by a list of all liked users.
I'm having a hard time wrapping my head around the SQL I need to pull data about other users that belong to the same group as the logged in user in my PHP application.
The data structure looks like this:
User Table
user_id
name
status
bio
Group Table
group_name
user_id
What I'm trying to do is create a page that shows the bios for all of the other members of the same group or groups that a user belongs to.
I've tried this SQL:
SELECT list.listname, list.user_id, list.groupname
FROM list
LEFT JOIN user_group ON list.user_id = user_group.user_id
WHERE user_group.user_id = 'test#testuser.com'
ORDER BY list.groupname
But I just get back the bio for test#testuser.com, and no other bios. If I remove the WHERE portion of the statement, I get all bios for all users, and not just the bios of users that are in the same group as my test#testuser.com. The logged in user may belong to more than one group.
Any ideas about how to grab this data?
This returns the groups for a given user:
SELECT l.groupname
FROM list l
WHERE l.user_id = 'test#testuser.com'
ORDER BY l.groupname;
If you want all users in the groups
SELECT l.listname, l.user_id, l.groupname
FROM list l LEFT JOIN
user_group ug
ON l.user_id = ug.user_id
WHERE l.groupname IN (SELECT l2.groupname
FROM list l2
WHERE l2.user_id = 'test#testuser.com'
)
ORDER BY l.groupname;
You can do it by self-joining the list table:
SELECT l.listname, l.user_id, l.groupname
FROM list l
LEFT JOIN user_group ug ON l.user_id = ug.user_id
INNER JOIN list l2 ON l2.groupname = l.groupname
AND l2.user_id = 'test#testuser.com'
ORDER BY l.groupname;
I am working on social networking site.
I've three tables one is user table which is used to store user details, another table is follow table which is used for followers following list.
In this table I am storing user_id and follower_id.
Third table is user_friends in this I'm storing user_id and friend_userid.
I want to search the user from my friends list and follow list. For this i've written query like this:-
select f.follower_id,uf.friend_userid,u.user_id,u.first_name,u.last_name from tbl_user u
LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id
LEFT JOIN tbl_follow f ON f.follower_id = u.user_id
where uf.friend_userid != '11'
AND u.first_name LIKE '%a%'
This query returning users only who are friends it is not returning the follow users.
Any help will be appreciated. Thanks in Advance.
You're joining tbl_follow on the Follower ID being equal to the User ID. I suspect that's probably not right.
If you don't already have one you'll need a user id key in the follower table to join on, then you can change your join to;
LEFT JOIN tbl_follow f ON f.userid = u.user_id
i've done this by using following query:-
select u.user_id,u.first_name,u.last_name from tbl_user u LEFT JOIN tbl_userfriends uf ON uf.friend_userid = u.user_id LEFT JOIN tbl_follow f1 ON f1.follower_id = u.user_id LEFT JOIN tbl_follow f2 ON f2.user_id = u.user_id where (uf.user_id = '11' OR f1.user_id = '11' OR f2.follower_id = '11') AND (u.first_name LIKE '%s%' OR u.last_name LIKE '%s%') AND u.status = '0' group by u.first_name
This query returning me all the users who are my followers, friends and to whom i am following.
I have a members table in which every site member is the unique id.
eg
id firstname secondname emailaddress country city gender
the second table is a friends table with the following structure
id meid friendid date
what query would i use to get friend suggestions of a particular user based on mutual friends and sorted accordingly. before i was using php to loop thru and collect mutual friends but as the site grew, php started misbehaving and running out of memory.
This is the function i was using
//-----------------------------------------------
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;
}
We say that B is possibly-friend of A if there is a large number of entries of the kind
(B, someguy) (someguy, A)
in the database, and there is no (B, A) entry.
We know the ID of user A and let it be AID. Then we can do:
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;
This will tell us all "possible friends" of A, including those that are
already friends of A. Then we have to exclude them:
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;
Then we need to populate the rest of the fields:
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;
This will return friend suggestions for AID, including how many people in common it has for every choice (e.g. "John Doe (15 friends in common)", etc.).
You want "friends of my friends, but who are not also my friends".
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
I have an application, very basic description:
Users login -> they post "activities" (like snowboarding)
Users have friends
Users can bind multiple friends to activities
Users can "like" activities created by friends
What I need is a query to check if the user is allowed to "like" an activity by one of their friends. They are only allowed when one of the users friends was bound to the target activity.
users: id, name
usersFriends: id, uid, friendUid
activities: id, description
activitiesUsers: id, activityId, uid
activitiesLikes: id, activityId, uid
I hope someone can help me with this query, and if possible to return true or false. I hope my question is clear and thanks for your time :)
This should produce a list of activities.id for all of the user's friends.
SELECT
activities.id AS canLikeId
FROM
users u
JOIN usersFriends uf ON u.id = uf.uid
JOIN activitiesUsers au ON uf.friendId = au.uid
JOIN activities a ON a.id = au.activityId
Wrapped in an EXISTS, it looks like:
SELECT activities.id FROM activities aCanLike
WHERE EXISTS (
SELECT
a.id AS canLikeId
FROM
users u
JOIN usersFriends uf ON u.id = uf.uid
JOIN activitiesUsers au ON uf.friendId = au.uid
JOIN activities a ON a.id = au.activityId
WHERE a.id = aCanLike.id
)
Or something with an IN() clause that attempts to get everything from activities owned by any of the user's friends.
SELECT
activities.*
FROM activities JOIN activitiesUsers ON activities.id = activitiesUsers.activityId
WHERE activitiesUsers.uid IN (
SELECT friendUid FROM usersFriends WHERE uid = $userid
)
Assuming you know the user's id and activity id at the time of the query, you could do something like:
SELECT COUNT(*) FROM activitiesUsers WHERE activityId = 'xx' AND uid IN (SELECT friendUid FROM usersFriends WHERE uid = 'xx')
Should return 0 if none of their friends are bound to the activity or a positive number if they have friends bound to that activity ...
This should do it:
select
count(*) as CanLike -- 0 if false, >= 1 if true
from
usersFriends uf
join
activitiesUsers au
on
uf.friendUid = au.uid
where
au.id = $activityId
and
uf.uid = $userId
SELECT COUNT(*) AS allowed
FROM userFriends
JOIN activitiesUsers ON (userFriends.uid = activitiesUsers.uid
AND activitiesUsers.activityId = $activity_id)
WHERE userFriends.uid = $user_id