ON
子句与子句的相似之处在于WHERE
都接受(简单或复杂)条件,这是一个布尔表达式。OR
运算符是一个布尔运算符,因此它既可以在 中使用,也可以在 中使用ON
,WHERE
因此请随意在连接条件中使用OR
任何您喜欢的方式来构建满足您要求的连接条件。
我认为您的查询基本上走在正确的轨道上。我只想指出一些你可能错过的事情,仅仅是因为你现在可能专注于其他事情。
一件事是联接的类型。我希望您的friends
表应该包含各个用户之间的所有现有链接,而不仅仅是用户5
和其他任何人之间的链接。因此,如果您使用左连接(即外连接)加入,您将获得friends
来自的所有链接,而不仅仅是 user的,这可能不是您想要的。当然,您可以添加一个带有类似条件的子句,但这基本上等同于没有该条件的内连接。因此,请改用内部联接。posts
friends
5
WHERE
friends.id IS NOT NULL
但是,您的WHERE
子句可能需要friends.acepted = 1
的当然是条件,因为您只希望用户 5 的朋友参与,我假设您的意思是那些被确认为朋友的人,因此acepted
应该是1
。
当然,用户在5
某个地方也必须有条件。在我看来,如果您从中派生一个表friends
将仅代表user 的朋友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)
也就是说,此查询检索作为用户 ( ) 的朋友 ( )acepted = 1
的用户 ID 。单个用户 ID 列由或组成:如果一个是,则拉另一个,反之亦然。5
followerid = 5 OR followingid = 5
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