我有这 3 个表:
POST (id, name, id_user, ..)
FRIENDS (id, followerid, followingid, acepted) /* acepted must be 1 to users be considered friends */
好的,所以我想从用户 5 那里获取所有 friend 的帖子。但是我在构造查询时遇到了很多麻烦。我知道我需要加入,问题是当前用户(id 5)可能是 followerid 或 followerid,所以我怎么知道?
我正在尝试类似的事情(但被废话阻止了):
SELECT posts.*,friends.id
FROM friends LEFT JOIN ON (friends.followerid = posts.id) OR (friends.following.id = posts.id)
但我真的不知道 ON 是否接受 OR 内部,我可以在这里得到一些提示吗?谢谢!
最佳答案
安ON
子句类似于 WHERE
子句,两者都接受(简单或复杂)条件,这是一个 bool 表达式。 OR
运算符是一个 bool 运算符,因此它可以在 ON
中使用就像WHERE
一样,所以请随意使用OR
您可以在连接条件中以任何方式构建满足您要求的连接条件。
我认为您的查询基本上是在正确的轨道上。我只想指出一些您可能会忽略的事情,因为您可能当时专注于其他事情。
有一件事是连接的类型。我期待你的friends
表应该包含各个用户之间的所有现有链接,而不仅仅是用户 5
之间的链接。和其他人。因此,如果您加入friends
至posts
使用左连接(这是一个外部连接),您将获得来自friends
的所有链接,不仅仅是用户 5
的,这可能不是您想要的。当然,你可以添加WHERE
条件如 friends.id IS NOT NULL
的子句,但这本质上相当于没有该条件的内部连接。因此,请改用内部联接。
但是,你的 WHERE
子句可能需要的是 friends.acepted = 1
当然,因为您只希望用户 5 的 friend 参与其中,并且我假设您指的是那些确认成为 friend 的人,因此 acepted
应该是1
.
当然,必须有一个条件,用户5
某处也有。在我看来,如果您从 friends
派生一个表格,那将是最简单的仅代表用户 5
的 friend ,并且它们也作为单列。 (也就是说,两个过滤器都将应用于派生表,而不是应用于联接的结果集。)这样,将 friend 加入 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)
也就是说,此查询检索用户 acepted = 1
的 friend ( 5
) 的用户 ID (followerid = 5 OR followingid = 5
)。单个用户 ID 列 friend_id
,由 followerid
组成或followingid
:如果是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
关于mysql - 检索用户好友的帖子,每个好友只有一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10859249/