tags:

views:

88

answers:

4

Hey guys quick question, I always use left join, but when I left join twice I always get funny results, usually duplicates. I am currently working on a query that Left Joins twice to retrieve the necessary information needed but I was wondering if it were possible to build another select statement in so then I do not need two left joins or two queries or if there were a better way. For example, if I could select the topic.creator in table.topic first AS something, then I could select that variable in users and left join table.scrusersonline. Thanks in advance for any advice.

SELECT * FROM scrusersonline
  LEFT JOIN users ON users.id = scrusersonline.id
  LEFT JOIN topic ON users.username = topic.creator
 WHERE scrusersonline.topic_id = '$topic_id'

The whole point of this query is to check if the topic.creator is online by retrieving his name from table.topic and matching his id in table.users, then checking if he is in table.scrusersonline. It produces duplicate entries unfortunately and is thus inaccurate in my mind.

+1  A: 

One option is to group your joins thus:

SELECT *
  FROM scrusersonline
  LEFT JOIN (users ON users.id = scrusersonline.id
             JOIN topic ON users.username = topic.creator)
 WHERE scrusersonline.topic_id = '$topic_id'
Marcelo Cantos
Is the nesting on your join condition OK? The 'ON users.id = scrusersonline.id' clause should be outside the parentheses, shouldn't it?
Jonathan Leffler
+1  A: 

Try:

select * from topic t 
     left outer join (
         users u 
         inner join scrusersonline o on u.id = o.id
     ) on t.creator = u.username

If o.id is null, the user is offline.

Shawn Simon
+2  A: 

You use a LEFT JOIN when you want data back regardless. In this case, if the creator is offline, getting no rows back would be a good indication - so remove the LEFT joins and just do regular joins.

SELECT *
  FROM scrusersonline AS o
  JOIN users AS u ON u.id = o.id
  JOIN topic AS t ON u.username = t.creator
 WHERE o.topic_id = '$topic_id'
Jonathan Leffler
I still just get my username printed twice if I echo the results. I guess it is ok since I just want a row count, but what are the difference in joins, they all seem to work the same regardless.
Scarface
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
cpharmston
nice article thanks cp, that really clears things up
Scarface
@Scarface: what happens depends on how many questions there are with a given topic ID, and whether the given user (creator) could be logged in twice (two entries in scrusersonline). Either of those could account for it -- I kind of assume that the username to creator join is unique (though not that user names on SO are not unique).
Jonathan Leffler
Ok sorry Jonathan I completely forgot about this post, but I tried your query and it does not work. It claims the following mysql_num_rows is not a valid resource
Scarface
This is not really making sense to me though because even if creator is an empty entry, there is still rows returned. It just returns the number of rows in scrusersonline, corresponding to that topic_id.
Scarface
k I just added AND topic.topic_id='$topic_id' and it seems to work as it should now
Scarface
A: 

Would not it be better to match against topic_id in the topics table by moving the condition to the join. I think it will solve your problem, since duplicates come from joining with the topics table:

SELECT * FROM scrusersonline
  JOIN users
    ON users.id = scrusersonline.id
  LEFT JOIN topic
    ON scrusersonline.topic_id = '$topic_id'
      AND users.username = topic.creator

By the way, LEFT JOIN with users is not required since you seem to search for the intersection between scrusersonline and users

newtover