I have three tables which are members, friends, and updates. I am trying to develop a query that will grab the updates for users who are friends with a specific user. For example get all the updates from all the friends of member X, USER:
X -> friend_1 > updated picture
-> friend_2 > added friend
-> friend_3 > updated status
Y -> friend_1 > updated picture
-> friend_2 > added friend
-> friend_3 > updated status
FRIENDS
friend_index
friend_id
logged_user_id *
MEMBERS
display_name
id *
UPDATES
update_id
member_id *
friend_id
update_action
So far this is the query that I have currently this gives me the updates of the current user and not the current users friends.
SELECT
U.update_id,
U.update_action,
U.update_hidden,
U.update_time,
U.member_id,
U.friend_id AS friend,
M.id,
M.display_name AS user,
F.friend_id,
F.logged_user_id
FROM member_friends F
JOIN members M
ON M.id = F.logged_user_id
JOIN member_updates U
ON U.member_id = F.friend_id
WHERE U.member_id = :id
ORDER BY U.update_id DESC
Thanks for taking a look.
You are joining the member_update with user.id thus leaving out the friends updates in the first join.
I would begin by selecting all the friends and then joining the member_update table with friends table and not user table
Query:
SELECT
U.member_id,
U.update_action,
FROM members M
JOIN member_friends F
ON M.id = F.logged_user_id
JOIN member_updates U
ON U.member_id = F.friend_id
WHERE M.id = :id
AND U.update_hidden <> 1
ORDER BY U.update_id DESC
Assuming logged_user_id is the user id which has firends friend_id
UPDATES.member_id is the user id to which that update belongs
Try this:
SELECT
U.update_id,
U.update_action,
U.update_time,
U.member_id,
U.id,
F.friend_id,
U.display_name AS user,
F.display_name AS friend
FROM members M
JOIN member_friends F
ON M.id = F.logged_user_id
JOIN member_updates U
ON U.member_id = F.friend_id
WHERE M.id = :id
AND U.update_hidden <> 1
ORDER BY U.update_id DESC
Related
I have two tables one is users and second is user_education.One users can have more than one education listing so i want to get the latest user education listing
users
===============
1-id
2-email
member_experience
==============
1-id
2-user_id
3-designation
user id 1 has 4 enteries in user_education so i want to get the last record enter designation of the user
original full query is like this
SELECT u.id,u.name,u.gender,u.email,file_managed.file_name,file_managed.file_path
from users as u
INNER JOIN member_experience on (SELECT uid FROM member_experience where member_experience.uid=u.id ORDER BY id DESC LIMIT 1)=u.id
LEFT JOIN file_managed on file_managed.id= u.fid
where u.user_type ='individual' AND u.gender='male'
"INNER JOIN member_experience on (SELECT uid FROM member_experience where member_experience.uid=u.id ORDER BY id DESC LIMIT 1)=u.id "
this portion has problem as users has many record in member_experience table but i want to get only one which is latest.
thanks
Devolve the acquisition of the last record to the where statement.
drop table if exists member_experience;
create table member_experience(id int auto_increment primary key, userid int);
insert into member_experience (userid) values
(1),(2),(1);
select * from member_experience
SELECT u.id,m.id
from users as u
join member_experience m on m.userid = u.id
where m.id = (SELECT max(m.id) FROM member_experience m where m.userid = u.id)
order by u.id
Or if you want to include those with no experience
SELECT u.id,m.id
from users as u
left join member_experience m on m.userid = u.id
where (m.id = (SELECT max(m.id) FROM member_experience m where m.userid = u.id)
or m.id is null)
and u.id < 4
order by u.id
I have 2 tables, a user's table and a friends table.
users
__________
user_id p.k
username
friends
__________
from_user
to_user
status ENUM('1', '2') //1 for sent/pending, 2 for accepted
primary key('from_user', 'to_user') // both also reference user_id
I'm relatively new to MySQL and have been trying to create a search query with the wildcard characters %% that will search based on the username and return rows of usernames, user_id, and status of people that are both friends and non friends to the current user in that order with a limit of 10. I would greatly appreciate any help and guidance on this matter. Below is what I have so far.
SELECT Users.user_id, Users.username, Friends.status
FROM Users
LEFT JOIN
Friends ON
Users.user_id IN Friends.to_user, Friends.from_user AND
'id of user' IN Friends.to_user, Friends.from_user
WHERE
Try this, to get the friends links:
select uf.user_id, uf.username, f.status
from users u
join friends f on u.user_id = f.from_user
join users uf on f.to_user = uf.user_id
where u.username like '%teddy%' and f.status = 2
LIMIT 10;
and this to get all the possible links, friends, sent/pending and not friends:
select uf.user_id, uf.username, f.status
from users u
left join friends f on u.user_id = f.from_user
left join users uf on f.to_user = uf.user_id
where u.username like '%teddy%'
LIMIT 10;
I have 3 tables
friends
posts
members
friends
========
id, to, from (user_id's), status
there are 3 status's -1 = denied, 0 = no response/new, 1 = accepted
posts
=======
p_id, user_id (same as member_id), text
members
========
member_id, f_name, l_name
If like to select the text from the post in 'posts' combine it with the users name from 'members' and only display posts where the user_id is in the 'friends' table.
I would like to know if it can be done, I've tried an IN () statement in my query which worked, but it creates a new problem with generating the csv inside the IN (). I'd perfer to do this through mysql, but if it can't be done I may use a global variable to store friend data (but then it will not be upto date or will have to be refreshed when a user gets a new friend).
As I understand it, you want to find the name and posts of all your friends, not any friend that's in the friend table at all...?
Your own user id being in $myId, this should do it (newest posts first);
EDIT: Added status check for friends
SELECT m.f_name, m.l_name, p.`text`
FROM members m
JOIN posts p
ON m.member_id = p.user_id
JOIN friends f
ON f.`to` = m.member_id OR f.`from` = m.member_id
WHERE (f.`from` = $myId OR f.`to`= $myId)
AND f.`status` = 1 AND m.member_id <> $myId
ORDER BY p.p_id DESC
Try this :
SELECT p.text,m.f_name,m.l_name FROM posts p
LEFT OUTER JOIN members m ON p.user_id=m.member_id
where p.user_id in(select id from friends);
OR
SELECT p.text,m.f_name,m.l_name FROM posts p
LEFT OUTER JOIN members m ON p.user_id=m.member_id
INNER JOIN friends f on p.user_id=f.id
If I understand correctly, you have a user_id and you want all the posts authored by "friends" of that user. This query starts at posts, joins that to friends (where the author is the "destination" of the friendship) (at which point the WHERE clause will filter out any non-friend posts), and then joins in members to fill out the author's name info.
SELECT
posts.p_id
posts.text,
CONCAT(members.f_name, " ", members.l_name)
FROM
posts
JOIN friends ON posts.user_id = friends.to
JOIN members ON posts.user_id = members.member_id
WHERE
friends.from = ?
GROUP BY posts.p_id
I added a subquery to get all your friends since I assumed that if you have these records
Friends
==================================
ID TO FROM STATUS
==================================
1 1 2 1
2 3 1 1
and your member_id = 1, your friends are 2, 3. right?
SELECT b.f_name,
b.L_name,
c.`text`
FROM
(
SELECT `to` friendID
FROM friends
WHERE `status` = 1 AND
`from` = ? -- change this to your ID
UNION
SELECT `from` friendID
FROM friends
WHERE `status` = 1 AND
`to` = ? -- change this to your ID
) a INNER JOIN members b
ON a.friendID = b.member_ID
LEFT JOIN posts c
ON a.friendID = c.user_id
I have the following tables:
team_members
userid
teamid
users
uid
name_f
name_l
friends
friend_id
friend_one
friend_two
I use the following statement to select uid and profile_pic of the users that belong to a certain team.
SELECT DISTINCT u.uid, u.profile_pic
FROM friends f, users u, team_members m
WHERE m.teamid =$team_var
AND u.uid = m.userid
I also have to run the following to select the uid and profile_pic of the users who are friends with the logged-in user and belong to a certain team.
SELECT DISTINCT u.uid, u.profile_pic
FROM friends f, users u, team_members m
WHERE m.teamid =$team_var
AND u.uid = m.userid
AND m.userid = f.friend_two
AND f.friend_one =$session_id
I'm looking for a way to join these two and instead of running 2 queries, run one single query that can order and list the users who are friends with the logged-in user at the top. So let's say that a certain team has 30 users and 5 of those users are friends with the logged-in user, I would like to have the first 5 listed in the while loop following the statement to be those of the friends with the rest of the 25 randomly shown.
Thanks for your time.
This can easily be solved with an outer join. You will probably not be able to use an outer join without the explicit join syntax. Here:
SELECT
u.uid,
u.profile_pic,
(friend_id IS NOT NULL) AS is_friend
FROM team_members m
INNER JOIN users u ON m.userid = u.uid
LEFT JOIN friends f ON m.userid = f.friend_two AND f.friend_one = $session_id
WHERE m.teamid = $team_var
ORDER BY
is_friend DESC,
m.userid
The first two tables are joined using an inner join, so only the members of a specific team are returned (because we are filtering on teamid).
The friends table is outer-joined to the result of the previous join. More specifically, we a joining the subset of friends where friend_one is the current user. All rows from the previous result set are returned, but also rows from the friends's subset are returned where matched. Where not matched, the friends columns are filled with NULLs.
Using the NULL (or rather NOT NULL) test, we can see which team member is a friend and which isn't. The result of the test is returned as a column and also used as a sorting criterion for the output rows.
You would need to create another column which has a value of "friend" or not "friend". You would then use that column as an ORDER BY. The column you create could be a subquery to determine if the other user is a friend or not. The following code is wrong because you need to hook the data from the outer query into the subquery, but it should look something like:
SELECT DISTINCT u.uid, u.profile_pic,
EXISTS (SELECT DISTINCT u.uid, u.profile_pic
FROM friends f, users u, team_members m
WHERE m.teamid =$team_var
AND u.uid = m.userid
AND m.userid = f.friend_two
AND f.friend_one =$session_id
) AS myColumn
FROM friends f, users u, team_members m
WHERE m.teamid =$team_var
AND u.uid = m.userid
ORDER BY myColumn
I might suggest this:
select u.uid, u.profile_pic
from team_members t
join team_members m on t.teamid = m.teamid
join users u on m.userid = u.uid
left join friends f on t.userid = f.friend_one and m.userid = f.friend_two
where m.userid != t.userid
and t.userid = $session_id -- This line can be removed to view all (test)
order by
--t.teamid, t.userid, -- This line can be added to order all (test)
(case when f.friend_id is null then 1 else 0 end case),
f.friend_id, m.userid
I'm using explicit join syntax (which is normally recommended these days) and using that case statement in the order by to get friends to the top. I don't have MySQL running here to test it, but the syntax should be pretty standard (I'm running something very similar on SQL Server).
I am working the friend table with mysql. I want to get friend userid and username form current username.
friend
=======
- id
- uid
- fid
Sample Data
===========
id uid fid
1 1 2
2 3 1
user
====
- id
- username
Sample Data
===========
id username
1 saturngod
2 snow
3 John
My current code is
SELECT `user`.id,`user`.username FROM friend
INNER JOIN User
ON user.id = friend.uid
WHERE friend.fid = ( SELECT `id` FROM `User` WHERE `username`='saturngod')
UNION
SELECT `user`.id,`user`.username FROM friend
INNER JOIN User
ON user.id = friend.fid
WHERE friend.uid = ( SELECT `id` FROM `User` WHERE `username`='saturngod')
It's working. I got the friend list. However, I feel , the sql is so long.
Can I reduce this sql and can we write without UNION in sql ?
You have already joined the tables, so the subselect is not needed.
SELECT u.id,u.username
FROM user u
INNER JOIN friend f ON (u.id = f.uid)
WHERE u.username='saturngod'
UNION ALL
SELECT u2.id,u2.username
FROM user u
INNER JOIN friend f ON (u.id = f.uid)
INNER JOIN user u2 ON (u2.id = f.fid)
WHERE u.username='saturngod'
Or you can do:
SELECT
u.id as user_id
,u.username
,u2.id as friend_id
,u2.username as friendname
FROM user u
INNER JOIN friend f ON (u.id = f.uid)
LEFT JOIN user u2 ON (u2.id = f.fid)
WHERE 'saturngod' = u.username
If you want one row per user you can do:
SELECT
u.id as user_id
,u.username
,GROUP_CONCAT(u2.id) AS friend_ids
,GROUP_CONCAT(u2.username) as friendnames
FROM user u
INNER JOIN friend f ON (u.id = f.uid)
LEFT JOIN user u2 ON (u2.id = f.fid)
WHERE 'saturngod' = u.username <<-- optional
GROUP BY u.id
SELECT CASE WHEN user_id="$id" THEN friend_id ELSE user_id END AS friendID
FROM user_friend WHERE user_id="$id" OR friend_id="$id" order by friendID ASC