简体   繁体   中英

How do I query two tables in this case?

For the one who down voted the question, could you please explain to me the reason? If this seems trivial to you, I would appreciate you pointing me to a reference; If this is a duplicate question, I would appreciate you pointing me to the earlier question. Thanks!

I have two tables, user and friend . The goal is as follows: A user a wants to get the information of another user b ; the returned info depends on whether they are friends or not. To be concrete, if they are friends, a can see b 's username and address ; if not, a can only see b 's username.

user table looks like:

id   username   address
1    abc        XXXX Rd. XXXX
2    def        XXXX Rd. XXXX
3    ghi        XXXX Rd. XXXX

friend table looks like:

id   id1   id2
1    1     2     // so 1 (abc) and 2 (def) are friends
2    1     3     // so 1 (abc) and 3 (ghi) are friends

2 ( def ) and 3 ( ghi ) are not friends. So basically there are the following two scenarios:

  1. user 2 ( def ) want to see user 3 ( ghi )'s info, the query returns ghi 's username only but not address
  2. user 1 ( abc ) want to see user 3 ( ghi )'s info, the query returns ghi 's username and address

Is it possible to do it using one query?

You can use a JOIN and check that the joined user's column exists (is not null) to determine if the friendship exists.

Eg if user def (2) wants info on user ghi (3):

SELECT
  user.username,
  user.address,
  friend.id AS are_friends
FROM user
INNER JOIN friend
  ON (friend.id1 = user.id AND friend.id2 = 2)
WHERE user.id = 3;

This should only return a row from your PDO handler if the link between user 2 and 3 exists. If it doesn't, the inner join will not work - if you used a left join here it would, but would return null for the are_friends field.

Of course you would replace 2 in that query with the current logged in user's ID, and replace 3 with the ID of the user that you want information for.

You would do a simple join, but for the issue of the ADDRESS, put that in a IF() construct. to only grab IF a friend.

select
      u.username as NameOfPossibleFriend,
      coalesce( u.Address, "not a friend" ) as FriendAddress
   from
      user u
         LEFT JOIN friend f
            on (     f.id1 = UserIDYourAreBasing
                 and f.id2 = IDOfPossibleFriend )
            OR (     f.id2 = UserIDYourAreBasing
                 and f.id1 = IDOfPossibleFriend )
   where
      u.id = IDOfPossibleFriend

So, I am starting with the user account looking explicitly for the ID of the person you are looking for as a possible friend. At a minimum, you KNOW of the possible friend's ID and want the name, but conditional on exposing the address.

So, now the LEFT-JOIN. Since I don't know the criteria of your table structure for ID1 vs ID2 as always being a low/high or high/low ID to see if available for a Friend. That is. Is it possible if user 1 and user 3 are friends, does the record ALWAYS get added to he table as ID1 = 1 and ID2 = 3 or is it possible to have ID1 = 3 and ID2 = 1 (alternate order, but same result... users 1 & 3 are friends).

So, the left join says to look where

ID1 is the original person and ID2 = the friend you are hoping to match.

OR

ID1 is the friend you are hoping to match and ID2 is the original person   

So, the left join will either find a record match and, then the ID won't be null and the friend's address WILL be pulled... If NO such match of the friends, the ID will be null from he friend's join and thus just a simple "not a friend" would be returned.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM