tags:

views:

1207

answers:

4

I had the following code

<?php

$getFriendQuery = "SELECT DISTINCT U.username FROM users as U INNER JOIN test_friends as F on U.Id = F.user_id WHERE F.friend_id = '{$userID}' && F.active=1";


$getFriendResult = mysql_query($getFriendQuery, $conn) or die (mysql_error());

$friendName = "";


while($getFriendFetch = mysql_fetch_assoc($getFriendResult)){
  $friendName .= $getFriendFetch['username'] . ", ";
}


$getFriendQuery  = "SELECT u.username FROM users u INNER JOIN test_friends f ON u.id = f.user_id WHERE (f.friend_id = '{$userID}' AND active=1) OR (f.user_id = '{$userID}' AND active=1)";

$getFriendResult = mysql_query($getFriendQuery, $conn) or die (mysql_error());


while($getFriendFetch = mysql_fetch_assoc($getFriendResult)){
  $friendName .= $getFriendFetch['username'] . ", ";
}


if (!empty($friendName)){
  echo "Your friends: " . $friendName ;
} else {
  echo "You do not have any friends yet";
  } 

?>

My code need 2 queries to get the "friends list". Is there a way to execute 1 query and can retrieve all friends list?

More information:

I got 2 tables. "Users table" and "test_friends" table. Users table has:

id represents user id => data type int(11)

username => data type varchar(256)

Test_friends table has:

user_id represents user id => data type int(11)

friend_id => data type int(11)

active => tinyint

+1  A: 

You should be able to do a union to do both queries in one. Your SQL will look like this:

SELECT U.username
FROM   users AS U
INNER JOIN test_friends AS F
ON     U.Id = F.user_id
WHERE  F.friend_id = '{$userID}'
AND    F.active = 1
UNION
SELECT u.username
FROM   users u
INNER JOIN test_friends f
ON     u.id = f.user_id
WHERE  ( f.friend_id = '{$userID}'
AND      active = 1 )
OR     ( f.user_id = '{$userID}'
AND      active = 1 )

It will also remove duplicates for you automatically, as if you included DISTINCT on the whole lot. (You do "UNION ALL" if you don't want that.)

Also, if you want to order the results, add "ORDER BY 1 ASC" on the end. You can only use result set column numbers in the ORDER BY clause with unions.

Union queries only work if the number and types of the columns returned in the result set by each sub-query are the same.

Aside: Your first query appears to be a subset of the second query, so you really only need to so the second query. I've left it as is as a demonstration of how to do unions, but you don't really need to in this case.

Evan
tried your code. Now working
roa3
It looks as though there is a mistake in this answer. Both queries above are identical so a UNION of these will result in the same set of records as executing just one instance of the query.If the above provided the correct result, you can simplify the query by executing just one SELECT query.
Michael
Hmmm, must have cut and pasted wrong from the original answer. I've fixed that now. Thanks.
Evan
+1  A: 

You can perform a UNION between the two queries. For example:

SELECT username FROM users WHERE username like '%billy%'
UNION 
SELECT username FROM users WHERE username like '%bob%'

will return all users with names like billy or bob. Combining your entire two queries above with a UNION should work.

Jess
A: 

As your first query appears to be a subset of your second query, you should only need to execute the second query.

I assume that in the Test_Friends table the user_id field represents the userid of the user and the friend_id field represents the userid of the user's friend.

If this is the case then you can execute the query:

SELECT DISTINCT U.username FROM Test_Friends F INNER JOIN Users U ON F.friend_id = U.user_id WHERE F.user_id = '{$userID}' AND F.active = 1

Michael
I tried your code. Not working
roa3
A: 

so you want names of $userID's friends AND names of users who have $userID as friend ? how about

select distinct U.username 
from users U 
inner join test_friends f 
on 
    (f.user_id = U.id AND f.friend_id={userID}) OR 
    (f.friend_id=U.id AND f.user_id={userID})
where active=1
jab11