简体   繁体   中英

Multiple inner joins in MySql not working

I have 3 tables :

useractivitylog

id   userid   activity_type  activity_id   date

which will store all user activities.

requestfriend

opid  userid  friendid  requesttime  message  source  requesttype  friendemail  status

which will store friends details. userid and friendid can be the user's id. If user A has send friend's request to user B, then userid will contain the id of A and friendid will be the id of B. So anyway B is the friend of A and A is the friend of B.

auth_user_profiles

id  user_id  first_name  last_name  profileimage

which stores user profile information.

What I need is to select all my friends activities from useractivitylog table. I tried with the following query. But it didnt worked.

    echo "select ua.*,rf.opid,aup.user_id,aup.first_name,aup.last_name,
        aup.profileimage from useractivitylog as ua INNER JOIN requestfriend as rf 
   INNER JOIN auth_user_profiles as aup on
   aup.user_id= IF (rf.userid='$userid',rf.friendid,rf.userid) 
   WHERE (rf.userid=$userid or rf.friendid=$userid)
   and rf.status='2' and ua.userid!=$userid";

Here, $userid is my user id. Actually what I want is to retrieve the profile information and the activities of users who are friends of mine. But know, it is returning all rows in useractivitylog table even if the userid is not in my friends list.

Can anyone help me to find an appropriate query for this. Thanks in advance.

This should work as you explained you need to get the activities of users who are friends with you, you first need to join useractivitylog table to requestfriend where friendid is in useractivitylog ie ON(rf.friendid =ua.userid) then you need to join auth_user_profiles table where userid from useractivitylog table is equal,ie ON(ua.userid=aup.user_id) and then use you where filter on rf.userid is equal to the provided user id ,i didn't get the point of using OR rf.friendid = $userid comparison when you asked for the friends activity then why comparing friend's id to the given user id

SELECT 
  ua.*,
  rf.opid,
  aup.user_id AS aup_user_id,
  aup.first_name,
  aup.last_name,
  aup.profileimage 
FROM
  useractivitylog AS ua 
  INNER JOIN requestfriend AS rf ON(rf.friendid =ua.userid)
  INNER JOIN auth_user_profiles AS aup ON(ua.userid=aup.user_id)

WHERE 
  rf.userid = $userid      
  AND rf.status = '2' 

Using a sub select

SELECT 
  ua.*,  
  aup.user_id AS aup_user_id,
  aup.first_name,
  aup.last_name,
  aup.profileimage 
FROM
  useractivitylog AS ua 
  INNER JOIN auth_user_profiles AS aup ON(ua.userid=aup.user_id)
WHERE 
ua.userid IN (
SELECT friendid  FROM  requestfriend WHERE userid =$userid AND `status` = '2' 
) 

You don't join properly. The only condition for a useractivitylog being linked to the other tables is that its user ID is not $userid. That is true for most records in the table, so you almost get a cartesian product (cross join).

BTW: You don't join auth_user_profiles properly either, because you compare with the string '$userid' instead of comparing with $userid.

Let's re-write the statement such that we retrieve the friends first and join the other tables with these:

select 
  ua.*,
  friend.opid,
  aup.user_id,
  aup.first_name,
  aup.last_name,
  aup.profileimage 
from 
(
  select distinct
    case when userid = $userid then friendid else userid end as id,
    opid
  from requestfriend
  where $userid in (userid, friendid) and status = '2'
) as friend
inner join useractivitylog as ua on ua.userid = friend.id
inner join auth_user_profiles as aup on aup.user_id = friend.id;

Try as below query

select * from useractivitylog a,requestfriend b,auth_user_profiles c 
   WHERE a.userid = b.userid and b.userid = c.userid;

You need to add a field to JOIN your first table on:

SELECT ua.*, rf.opid, aup.user_id, aup.first_name, aup.last_name, aup.profileimage 
  FROM useractivitylog as ua 
       INNER JOIN requestfriend as rf on fieldname = fieldname
       INNER JOIN auth_user_profiles as aup on aup.user_id = IF (rf.userid='$userid',rf.friendid,rf.userid) 
 WHERE (rf.userid=$userid or rf.friendid=$userid)
   AND rf.status='2' 
   AND ua.userid!=$userid

You could go from the other side to your data... Start with selecting all your friends and if you have them, get their data:

SELECT 
  ua.*,
  rf.opid,
  aup.user_id,
  aup.first_name,
  aup.last_name,
  aup.profileimage
FROM
  requestfriend AS rf
JOIN 
  useractivitylog AS ua ON (ua.userid = rf.friendid)
JOIN 
  auth_user_profiles AS uap ON (uap.userid = rf.friendid)
WHERE rf.userid = $userid AND rf.status = '2'

The rest with the vice-versa connection in your requestfriend table should be no problem.

Since the friendrequests should be not as much as the activities, this might lead to better performance in case you have loads of data...

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