【问题标题】:MySQL: 3 table join query?MySQL:3表连接查询?
【发布时间】:2009-12-07 06:58:34
【问题描述】:

我有三个表(user、friends、posts)和两个用户(user1 和 user2)。

当 user1 将 user2 添加为好友时,user1 可以像在 Facebook 上一样看到 user2 的帖子。但只有在 user1 将 user2 添加为好友的日期之后的帖子。我的查询是这样的:

$sql = mysql_query("SELECT * FROM posts p JOIN friends f ON 
        p.currentuserid = f.friendid AND p.time >= f.friend_since OR 
        p.currentuserid='user1id' WHERE f.myid='user1id' 
        ORDER BY p.postid DESC LIMIT 20");

它一直运行良好,但有一个小问题.....! 它显示 user2,user3(所有用户作为 user1 的朋友)单次发布,但显示 user1 发布多个.......即

user2. hi
user1. userssfsfsfsfsdf
user1. userssfsfsfsfsdf
user3. dddddddd
user1. sdfsdsdfsdsfsf
user1. sdfsdsdfsdsfsf

但我在数据库中它是单个条目/帖子为什么会发生......!!

我该如何解决?

【问题讨论】:

  • 有人能把这个查询分开,让它更清晰吗?在那里添加一些新行并删除 PHP 语法,因为这个问题与 PHP 无关。

标签: mysql join


【解决方案1】:

我不是 SQL 专家,但我认为您的问题在于 JOIN 条件。我看不到如何加入帖子和朋友并获得所需的结果。 SQL 专家可能知道这一点,但对我来说太难了。

如果我是你,我会将问题分为两部分:

  1. 选择用户自己的帖子

  2. 选择用户朋友的帖子

例如,您可以通过使用 2 个不同的条件并在子查询中与朋友表进行联接(我没有测试过!):

select * 

from posts p

where 

p.currentuserid = 'user1id'

or 

p.postid in 

(
select p2.postid
from posts p2 
join friend f on p2.currentuserid = f.friendid 
where p2.time >= f.friend_since and f.myid='user1id' 
)

另一种方法是使用联合(也未测试..):

select * 

from posts p

where 

p.currentuserid = 'user1id'

union 

select p2.*

from posts p2 

join friend f on p2.currentuserid = f.friendid 

where p2.time >= f.friend_since and f.myid='user1id' 

【讨论】:

    【解决方案2】:

    我认为,最简单的解决方案是对列 posts.userId 使用 GROUP BY 语句来删除重复条目。但是,它不是解决问题的优化方法。

    【讨论】:

      【解决方案3】:

      您获得 user1 的所有朋友的帖子的原因是您没有限定查询应该返回哪个朋友的帖子。

      WHERE 子句之前添加一个f.friendid = 'user2id'(或任何列名)。

      【讨论】:

        【解决方案4】:

        您确实应该对架构的外观有所了解,这样我们就不必做出如此多的假设。我假设user 的主键是id,而friends 有一个userid 和一个friendid 字段。我还假设 posts.currentuserid 是创建帖子的用户的 ID。如果不是,请将其替换为 posts.userid 或任何正确的字段。

        您的查询无法正常工作的原因是您至少需要 2 个联接。创建查询时,最简单的方法是从您拥有的内容开始,然后逐步完成您想要的内容,一次加入一个。这是获取特定用户可以阅读的帖子的查询:

        SELECT p.*
        FROM user u
        JOIN friends f ON u.id = f.userid
        JOIN posts p ON ((u.id = p.currentuserid) OR (f.friendid = p.currentuserid AND p.time >= f.friend_since))
        WHERE u.id = ?
        ORDER BY p.postid DESC LIMIT 20
        

        第二个连接是肉所在的位置。它指定要阅读帖子 (a) 必须由您撰写或 (b) 必须由您的朋友在您加为好友后撰写。

        如果您还想获取创建帖子的用户的姓名(假设 user.name 持有用户名),您需要第三次加入:

        SELECT pu.name as 'Posted By', p.*
        FROM user u
        JOIN friends f ON u.id = f.userid
        JOIN posts p ON ((u.id = p.currentuserid) OR (f.friendid = p.currentuserid AND p.time >= f.friend_since))
        JOIN user pu ON p.currentuserid = pu.id
        WHERE u.id = ?
        ORDER BY p.postid DESC LIMIT 20
        

        【讨论】:

          猜你喜欢
          • 2015-08-20
          • 2014-11-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多