I have scenario in which I am storing user email in a table user_info. Its structure is given as below.
user_info(_id,email)
However one user can be friend of other users.So for that purpose i have another table user_friend. Its structure is given below
user_friend(_id,userA , userB)
Now suppose there are 5 user A,B,C,D and E. We got table values something like this.
user_info
_id email
1 A#...
2 B#...
3 C#...
4 D#...
5 E#...
user_friends
_id userA userB
1 1 2
2 1 3
3 1 4
4 5 1
it's mean A is friend of B,C,D and E. i want to get email of these but i am unable to think about any proper query.
i am using left join but it does not seems to work properly
Getting friends of 1(A#...). But it's not working properly
SELECT DISTINCT email FROM user_info AS UI
LEFT JOIN user_friends AS UF
ON UI._id = UF.userA
LEFT JOIN user_friends AS UF2
ON UI._id = UF2.userB
WHERE UF2.userA = '1' || UF2.userB ='1'
Any Suggestions?
Use UNION to get all friends email
(SELECT
u2.email
FROM user_info u
LEFT JOIN user_friends f ON f.userA = u._id
LEFT JOIN user_info u2 on u2._id = f.userB
WHERE u._id = 1)
UNION
(SELECT
u2.email
FROM user_info u
LEFT JOIN user_friends f ON f.userB = u._id
LEFT JOIN user_info u2 ON u2._id = f.userA
WHERE u._id = 1)
It will be Something like this.
SELECT email from user_info WHERE _id IN (select userA from user_friends where userB = '1' Union All select userB from user_friends where userA = '1')
Related
How do I get friend list from Friends table with counts of friends of my friends (Count not of my friends)
Friends table"
tbl_users_friends
Field 1: id
Field 2: user_id
Field 3: friend_user_id
and I need the out put as:
A has following friedns:
x (10)
y (2)
z (0)
Above is the list of my friends and in parenthesis contains their friends count.
Thanks
select user_id, count(*) cnt
from Friends
where user_id in
(select friend_user_id
from Friends
where user_id = user_id_of_A)
group by user_id
Try something like this:
select u.user_id, u.name, count(uf1.id) as num_friends
from tbl_users_friends uf
inner join tbl_users u on u.user_id = uf.friend_user_id
left join tbl_users_friends uf1 on uf1.user_id = uf.friend_user_id
where uf.user_id = 1
group by u.user_id, u.name
http://sqlfiddle.com/#!9/10033/1
You need to ajust the users table and column names.
Another solution with a subselect but without group by:
select u.user_id, u.name, (
select count(*)
from tbl_users_friends uf1
where uf1.user_id = uf.friend_user_id
) as num_friends
from tbl_users_friends uf
inner join tbl_users u on u.user_id = uf.friend_user_id
where uf.user_id = 1
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 want to show the conclusion of all users.
I have 3 tables.
table post
post_id(index) user_id
1 1
2 3
3 3
4 4
table photo
photo_id(index) user_id
1 2
2 4
3 1
4 1
table video
photo_id(index) user_id
1 4
2 4
3 3
4 3
and in table user
user_id(index) user_name
1 mark
2 tommy
3 john
4 james
in fact, it has more than 4 rows for every tables.
I want the result like this.
id name post photo videos
1 mark 1 2 0
2 tommy 0 1 0
3 john 2 0 2
4 james 1 1 2
5 .. .. .. ..
Code below is SQL that can work correctly but very slow, I will be true appreciated if you help me how it using LEFT JOIN for it. Thanks.
SQL
"select user.*,
(select count(*) from post where post.userid = user.userid) postCount,
(select count(*) from photo where photo.userid = user.userid) photoCount,
(select count(*) from video where video .userid = user.userid) videoCount
from user order by user.id"
(or ORDER BY postCount, photoCount or videoCount ASC or DESC as i want )
I done researched before but no any helped me.
SELECT u.user_id,
u.user_name,
COUNT(DISTINCT p.post_id) AS `postCount`,
COUNT(DISTINCT ph.photo_id) AS `photoCount`,
COUNT(DISTINCT v.video_id) AS `videoCount`
FROM user u
LEFT JOIN post p
ON p.user_id = u.user_id
LEFT JOIN photo ph
ON ph.user_id = u.user_id
LEFT JOIN video v
ON v.user_id = u.user_id
GROUP BY u.user_id
ORDER BY postCount;
Live DEMO
Your method of doing this is quite reasonable. Here is your query:
select user.*,
(select count(*) from post where post.userid = user.userid) as postCount,
(select count(*) from photo where photo.userid = user.userid) as photoCount,
(select count(*) from video where video.userid = user.userid) as videoCount
from user
order by user.id;
For this query, you want the following indexes:
post(userid)
photo(userid)
video(userid)
user(id)
You probably already have the last one, because user.id is probably the primary key of the table.
Note that a left join approach is a bad idea in this case. The three tables -- posts, photos, and videos -- are independent of each other. If a user has five of each, then joining them together would produce 125 intermediate rows. If a user has fifty of each, it would be 125,000 -- a lot of extra processing.
Your answer is probably slow as it is using a correlated sub-query i.e. the sub query is running once for each user_id (unless the optimizer is doing something smart - which shouldn't be counted on).
You could use a left outer join and count or use something temporary like:
SELECT u.user_id,
u.user_name,
ph.user_count AS 'photoCount',
p.user_count AS 'postCount',
v.user_count AS 'videoCount'
FROM user u
INNER JOIN ( SELECT user_id,
COUNT(*) AS user_count
FROM photo
GROUP BY user_id
) ph
ON ph.user_id=u.user_id
INNER JOIN ( SELECT user_id,
COUNT(*) AS user_count
FROM post
GROUP BY user_id
) p
ON p.user_id=u.user_id
INNER JOIN ( SELECT user_id,
COUNT(*) AS user_count
FROM video
GROUP BY user_id
) v
ON v.user_id=u.user_id
There are pros and cons for both (depending on indexes). Always have a look at the query plan (using EXPLAIN for MySQL).
I have a table named friends;
friends
id uid fid
1 1 2 (1 is a friend of 2 and vice versa)
2 1 3 (1 is a friend of 3 and vice versa)
3 4 1 (1 is a friend of 4 and vice versa)
4 5 1 (1 is a friend of 5 and vice versa)
And a corresponding table for users;
users
uid name
1 mike
2 john
3 karl
4 mary
5 tony
This doesn't seem to do the trick:
SELECT name FROM users LEFT JOIN friends ON friends.uid=users.uid WHERE friends.uid='1' OR friends.fid='1'
What should my query be to get all the names of mike's friends?
This should do it just fine with a single, easy to index, query;
SELECT name FROM users u
JOIN friends f
ON u.uid = f.uid OR u.uid = f.fid
WHERE (f.uid=1 OR f.fid=1)
AND u.uid<>1;
Demo here.
Untested:
SELECT name from friends LEFT JOIN users on users.uid=friends.fid where friends.uid=1 UNION
SELECT name from friends LEFT JOIN users on users.uid=friends.uid where friends.fid=1
This may look a little strange if anyone is ever friends with themselves.
try one of these:
SELECT a.uid as UserID,
a.`Name` as UserName,
c.`Name as FriendsName
FROM users a LEFT JOIN friends b on a.uid = b.uid
LEFT JOIN users c on b.fid = c.uid
OR
SELECT a.uid as UserID,
a.`Name` as UserName,
GROUP_CONCAT(c.`Name`) as FriendsList
FROM users a LEFT JOIN friends b on a.uid = b.uid
LEFT JOIN users c on b.fid = c.uid
GROUP BY a.uid
As in your prequel question, you need to cover both foreign keys to the user table to get all his friends:
SELECT users.*
FROM (
SELECT uid FROM friends WHERE fid = 1
UNION ALL
SELECT fid FROM friends WHERE uid = 1
) f
JOIN users USING (uid)
Switch friends and users in your query and I think you'll get what you want.
In other words:
SELECT name FROM friends LEFT JOIN users ON friends.uid=users.uid WHERE friends.uid='1' OR friends.fid='1'
I think this is right SELECT name FROM users LEFT JOIN friends ON friends.uid=users.uid WHERE friends.uid=1 OR friends.fid=1
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Self referencing relation with followers|friends users
Hi there.
I have two tables called users and users_friends.
users:
id INT
username VARCHAR
.....
users_friends:
user_id INT
friend_id INT
PRIMARY KEY (`user_id`,`friend_id`)
How can I get the information about a specific users friends? Let's say I want to list friends associated with the user with an id of 5.
Can't get my joins working, everything I try ends up with no result. Any ideas? This should be I simple query with two INNER JOIN I think but can't manage.
Then a second question is how do I structure this using Kohana 3.1 ORM? Perhaps I shouldn't?
EDIT: Anyone have an idea about doing this with Kohana 3 ORM?
What about something like this :
select users.*
from users
inner join users_friends on users_friends.friend_id = users.user_id
where users_friends.user_id = 5
SELECT *
FROM `users` AS u
INNER JOIN `users_friends` AS uf ON u.id = uf.user_id
WHERE u.id = '5'
this is the query with INNER JOIN
if all of the information is stored in users you will need to join users once more
SELECT ufu.*
FROM `users` AS u
INNER JOIN `users_friends` AS uf ON u.id = uf.user_id
INNER JOIN `users` AS ufu ON uf.friend_id = ufu.user_ud
WHERE u.id = '5'
Ofcourse a JOIN is possible, but that wont be faster then a simple query like:
SELECT *
FROM users
WHERE id IN (
SELECT friendID FROM user_friends WHERE userID=5
)
But, this only lists the friends from user 5. If you want the other way around, so list the people that say user 5 is a friend, this query is also easier to alter.
SELECT *
FROM users
WHERE id IN (
SELECT userID FROM user_friends WHERE friendID=5
)
isn't it a simple:
Select friend_id from users_friends where user_id = 5
5 being the users id.
Off the top of my head:
SELECT friend_id, username
FROM users_friends JOIN users
ON users_friends.friend_id = users.id
WHERE user_id = 5;