MySQL SELECT 2表与INNER JOIN

时间:2012-03-22 23:35:23

标签: php mysql database

我一直在研究一些MySQL连接,但这个让我有点困惑。 我有3个表,friendspostsactivity

postsactivity都有一个字段userid,表示该记录所属的用户。 friends包含字段useridfriendid,代表两个用户是朋友。

如果可能,我想设计一个查询,该查询将显示来自用户的postsactivity中的记录,该用户是登录用户的朋友。

我尝试了以下查询:

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)'

但是,当我运行上述查询时,出现以下错误:

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

非常感谢任何帮助:)

3 个答案:

答案 0 :(得分:4)

您可能需要UNION。如果两个表postsactivity具有相同的列数(相同的顺序和类似的类型),则以下内容将起作用。如果没有,则SELECT列表中需要进行一些调整:

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)'

如果两个表有不同的字段,那么您应该调整2个选择列表,例如:

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
    ...

答案 1 :(得分:1)

两件事:

除非必须,否则永远不要在MySQL中使用显式连接,它们可能会降低查询的性能,有时会非常严重。

您的查询结构不正确。你不能在加入a和f的on子句中使用p,你只能使用a和f中的引用,比如说:

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

你最想要的是两个查询,如:

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'

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'

如果两个表具有相同的列,那么您可以使用类似联合的东西将它们放在一个查询中:

(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')

如果它们没有相同的列,则要么必须使两个选择的结果具有包含特定列和别名的相同列,要么返回两个查询。

如果你需要从这个结果集中排序,那么你需要一个子查询,但是要注意,MySQL中的各种子查询已经知道在应用程序逻辑而不是SQL中做得更好。其他数据库引擎有更好的时间。

答案 2 :(得分:1)

这里有几个问题:

  1. 乳清使用表的别名,您不需要AS关键字。 “来自帖子p”就足够了。
  2. 您对活动表没有任何约束,但它是您的select语句的一部分。这将进行自然连接,但会生成一个糟糕的笛卡尔积,并将返回整个表,因为您没有被我用户过滤。
  3. 要解决问题2,您需要在Claus的位置添加另一个条件,例如:

        AND a.userid = p.userid
    

    或者添加另一个连接子句:

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