views:

509

answers:

9

I have 2 tables:

'Users' Table

id      username  
----    -------- 
0001    user1          
0002    user2          
0003    user3          
0004    user4     

'Friends' Table

user_id  friend_id  friend
-------  ---------  ------
0001     0004       1
0002     0004       1
0005     0004       0

How do I display all user4 friends' name? if in friends table, friend column, 1 indicates they are friend, 0 indicate they are still not friend.

I use INNER JOIN, which looks like this:

SELECT users.username
FROM `users`
INNER JOIN `friends` ON users.id = friends.friend_id
WHERE friends.user_id = 0004
  AND friend = 1;

But what I get is:

user4 and user4 instead of user1 and user2

Can help me?

A: 
SELECT u.username
FROM Friends f, Users u
WHERE f.friend = 1 AND 
 ((f.friend_id = @userid AND f.user_id = u.id) OR
  (f.user_id = @userid AND f.friend_id = u.id))
Mehrdad Afshari
+1  A: 
select u.username
from friends f, users u
where f.friend_id='0004' and f.friend=1 and f.id=u.user_id;

Edit: This is the same as:

select u.username
from friends f inner join users u on f.id=u.user_id
where f.friend_id='0004' and f.friend=1;
tehvan
There is no u.user_id field.
Simon Hughes
thanks for pointing that out. fixed it (and some other things)
tehvan
I tried all answer. Just change the u.user_id to u.id, its working...But the chris mehrdad and gordon answers not working..
roa3
you probably have the id columns set up as text (e.g. varchar). You might want to consider changing them into int(11). Internal IDs are usually stored as int.
tehvan
+3  A: 
SELECT users.username
FROM `users`
INNER JOIN `friends` ON users.id = friends.user_id
WHERE friends.user_id = 0004
  AND friend = 1;
Chris Simpson
I tried few times, not working..
roa3
i think the "WHERE" needs to be "friends.friend_id = 0004" instead of user_id
Jarod Elliott
Yup, after I change from friends.user_id to friends.friend_id, its working now.. Thanks a million
roa3
+1  A: 

Are you sure you don't want to link the friends table to the users table on the user_id instead of the friend_id? Then change the where clause to use the friend_id instead of the user_id. There's different ways of formatting the join, but the way your doing it using an inner join looks fine.

SELECT users.username
FROM `users` 
INNER JOIN `friends` ON users.id = friends.user_id 
WHERE friends.friend_id = 0004   
AND friend =1
GordonB
+4  A: 
SELECT u.username
FROM   Friends f, Users u
WHERE  f.user_id = u.id
       AND f.friend = 1
       AND f.friend_id = '0004'
Simon Hughes
no need to specify user id 0004??
roa3
The @userID can be used as a parameterised query, so you can pass in the '0004' as the parameter. I've modified the select above so you can run it direct.However, you should really be using parameterised queryies to protect against SQL injection attacks. Never append '0004' to your query.
Simon Hughes
What I mean is, what is someone entered' OR 1=1 --You would end up with AND f.friend_id = '' OR 1=1 --0004'
Simon Hughes
thanks.. I will take care of mysql injection
roa3
+1  A: 

Do you mean like this?

SELECT u.username
FROM friends AS f
INNER JOIN users AS u USING user_id
WHERE f.friend_id = 0004 AND f.friend = 1
Bart S.
+1  A: 
select U.Username
from
    Users as U
    inner join Friends as F on U.Id = F.user_id and F.friend = 1
where
    F.friend_id = '0004'

If the friend table is just a mapping table then you not want to map both ways?

select U.Username
from
    Users as U
    left outer join
    (
     select 
      F.user_id as Id
     from
      Friends as F
     where
      F.friend_id = '0004'
     and
      F.friend = 1

    ) as Mapping1 on Mapping1.Id = U.id
    left outer join
    (
     select 
      F.friend_id as Id
     from
      Friends as F
     where
      F.user_id = '0004'
     and
      F.friend = 1

    ) as Mapping2 on Mapping2.Id = U.id

where
    Mapping1.Id is not null or Mapping2.Id is not null
Damien McGivern
This is too advanced for me. Btw, does your method would be faster(faster in retrieving data) then the others?
roa3
I assume you refer to the second query. It's a question of completness if you want the bidirectional lookup then this is so far the only query that does the job. As for speed that will depend on you table field indexes.
Damien McGivern
A: 

dmcgiv has an important point that you need to think about if the friend mapping is bidirectional (i.e., if A is friends with B then B is automatically friends with A). You need to check whether the user you're interested in is on either side of the Friends table mapping.

You can either do it dmcgiv's way, or another way would be to just insert links in both directions into the Friends table when you add a friendship. For example, if user 0004 is friends with user 0006, you would insert into the Friends table:

user_id | friend_id | friend
0004    | 0006      |   1
0006    | 0004      |   1

I don't think you really need a friend column, by the way. Unless there's some reason to track "non-friends" you can just delete the mapping from the Friends table if the friendship ends.

Jesse Smith
A: 

select username from users us where us.id in ( select f.[user_id] from users u inner join friends f ON u.id = f.friend_id where f.friend=1)