从用户的朋友那里检索帖子,每个朋友只有一行



我有这 3 个表:

POST (id, name, id_user, ..)
FRIENDS (id, followerid, followingid, acepted) /* acepted must be 1 to users be considered friends */

好的,所以我想从用户 5 那里获取所有朋友的帖子。 但是我在构建查询时遇到了很多麻烦。 我知道我需要加入,问题是当前用户(ID 为 5)可能是关注者或关注 ID,所以我怎么知道?

我正在尝试类似的东西(但被废话阻止了):

SELECT posts.*,friends.id 
                    FROM friends LEFT JOIN ON (friends.followerid  = posts.id) OR (friends.following.id = posts.id)

但我真的不知道ON是否接受OR内部,我可以在这里得到一些提示吗? 谢谢!

ON 子句类似于WHERE子句,因为它们都接受(简单或复杂)条件,这是一个布尔表达式OR运算符是一个布尔运算符,因此它可以在ONWHERE中使用,因此请随意OR连接条件中以任何您喜欢的方式使用,以构建满足您要求的一种。

我认为您的查询基本上走在正确的轨道上。我只想指出一些你可能错过的东西,仅仅是因为你现在可能专注于其他事情。

一件事是联接的类型。我希望您的friends表应该包含不同用户之间的所有现有链接,而不仅仅是用户5与其他任何人之间的链接。因此,如果您使用联接(这是外联接)friends连接到posts,您将从friends获得所有链接,而不仅仅是用户5,这可能不是您想要的。当然,您可以添加带有 friends.id IS NOT NULL 等条件的 WHERE 子句,但这实质上等同于没有该条件的内部连接。因此,请改用内部联接。

但是,您的WHERE条款可能需要的是friends.acepted = 1条件,当然,因为您只希望用户 5 的朋友参与其中,我假设您的意思是那些被确认为朋友的人,因此应该acepted 1

当然,用户在某个地方5也必须有一个条件。在我看来,如果您从friends中派生出一个表,该表仅代表用户5的朋友,并且它们也作为单个列,那将是最简单的。(也就是说,这两个筛选器都将应用于派生表,而不是联接的结果集。这样,将好友加入posts表会更容易,因为您的加入条件会更简单。以下是派生此类表的一种方法:

SELECT
  id,
  CASE followerid WHEN 5 THEN followingid ELSE followerid END AS friend_id
FROM friends
WHERE acepted = 1
  AND (followerid  = 5 OR followingid = 5)

也就是说,此查询检索作为用户5followerid = 5 OR followingid = 5 ) 的好友 ( acepted = 1 ) 的用户 ID。单用户 ID 列 friend_idfolloweridfollowingid 组成:如果一个5,则拉取另一个,反之亦然。

这就是在最终查询中使用此派生表的方式:

SELECT
  p.*,
  f.id  /* there's an `id` column in `posts`, so it might be a good idea
           to assign `friends.id` a distinct alias, like `friends_id` */
FROM (
  SELECT
    id,
    CASE followerid WHEN 5 THEN followingid ELSE followerid END AS friend_id
  FROM friends
  WHERE acepted = 1
    AND (followerid  = 5 OR followingid = 5)
) AS f
  INNER JOIN posts AS p ON p.id_user = f.friend_id

一种方法是使用联合

SELECT posts.*,friends.id FROM friends LEFT JOIN posts ON 
(friends.followerid  = posts.id) where friends.acepted = 1 and posts.id_user = 5
UNION
SELECT posts.*,friends.id FROM friends LEFT JOIN posts ON 
(friends.following.id = posts.id) where friends.acepted = 1 and posts.id_user = 5

您的查询应该有效:

SELECT posts.*, friends.id 
FROM friends LEFT JOIN
     posts
     ON (friends.followerid  = posts.id) OR
        (friends.following.id = posts.id)

但是,"on"语句中的"or"通常效率低下。 例如,它们对索引的使用造成了严重破坏。 请注意,当有关注者和关注者时,此方法将为每个帖子生成多行。

另一种表述是将两者放在同一行上:

SELECT posts.*, follower.id, following.id 
FROM posts left outer join
     friends follower
     ON follower.followerid = posts.id left outer join
     friends following
     on following.followingid = posts.id
where follower.id = 5 or following.id = 5

最新更新