简体   繁体   中英

MySQL SELECT 2 tables with an INNER JOIN

I've been working on some MySQL Joins but this one has got me a little confused. I have 3 tables, friends , posts and activity .

Tables posts and activity both have a field userid which represents the user that the record belongs to. friends contains the fields userid and friendid to represent two users being friends.

If possible, I would like to design a query which will display the records in posts AND activity from a user which is friends with the logged in user.

I have tried the following query:

SELECT p.*, a.*
    FROM posts AS p, activity AS a
    INNER JOIN friends f ON (p.userid = f.friendid)
    WHERE f.userid = '(Logged In User ID)'

However, when I run the above query, I get the following error:

Unknown column 'p.userid' in 'on clause'

Any help would be much appreciated :)

You probably need a UNION . The following will work if the two tables, posts and activity have the same number of columns (in same order and similar type). If not, some adjustment is needed in the SELECT lists:

SELECT p.*
    FROM posts AS p
        INNER JOIN friends f ON p.userid = f.friendid
    WHERE f.userid = '(Logged In User ID)'
UNION ALL
SELECT a.*
    FROM activity AS a
        INNER JOIN friends f ON a.userid = f.friendid
    WHERE f.userid = '(Logged In User ID)'

If the two tables have different fields, then you should adjust the 2 select lists, with something like:

SELECT p.id
     , p.userid
     , p.post_text     AS text
     , p.post_date     AS date
     , NULL            AS action
    FROM posts AS p
    ...
UNION ALL
SELECT a.id
     , a.userid
     , NULL            AS text 
     , a.activity_date AS date
     , a.action        AS action
    FROM activity AS a
    ...

two things:

Never use explicit joins in MySQL unless you have to, they may decrease the performance of the query, sometimes very severely.

Your query isn't structured correctly. You can't use p in an on clause joining a and f, you can only use references from a and f, say:

select p.*, a.*
  from posts p, activity a inner join friends f on (a.userid = f.friendid)...

most likely what you want is two queries like:

select a.* from activity a, friends f, users u
where a.userid = f.friendid
  and u.userid = f.userid;
  and u.userid = 'logged in user'

and

select p.* from posts p, friends f, users u
where p.userid = f.friendid 
  and u.userid = f.userid
  and u.userid = 'logged in user'

if both tables have the same columns, then you can put both in a single query using something like a union:

(select a.* from activity a, friends f, users u
    where a.userid = f.friendid
      and u.userid = f.userid
      and u.userid = 'logged in user'
) union (select p.* from posts p, friends f, users u
    where p.userid = f.friendid 
      and u.userid = f.userid
      and u.userid = 'logged in user')

if they don't have the same columns, then either you have to make the result of the two selects have the same columns with specific columns and aliases, or go back to two queries.

If you need to sort from this result set, then you'll need a subquery, but be warned, subqueries in MySQL with sorts have been known to be better done in application logic rather than SQL. Other database engines have a better time with this.

Several problems here:

  1. Whey of are using aliases for tables, you don't need the AS keyword. "from posts p" is sufficient.
  2. You don't have any constraints to the activity table, but it's apart of your select statement. This will do a natural join, but will produce a bad Cartesian product and will return that whole table, because you aren't filtering it by the user I'd.

To fix issue 2, you need to add another condition to the where Claus, like:

    AND a.userid = p.userid

Or add another join clause:

   INNER JOIN activity a on a.userid = p.userid

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