基于条件的多连接获取唯一记录

时间:2014-06-27 17:48:39

标签: mysql

我有4个表:postsusersmentionsfollowing

posts
----------------------------
id  |  user_id  |  post_text
1      1           foo
2      1           bar
3      2           hello
4      3           jason

users
------------
id  |  name
1      jason
2      nicole
3      frank

mentions
--------------------------
id  |  post_id  |  user_id
1      4           1


following
-------------------------------------------------
id  |  user_id  |  user_id_of_user_being_followed
1      1           2

posts包含发布了一些文字的用户的user_id users具有用户ID和用户名 mentions具有提及一个或多个其他用户的帖子的帖子ID和用户ID following具有用户ID和他们关注的用户(用户可以跟随0到多个用户)

我尝试做的是返回给定用户关注的用户的所有帖子,加上提及该用户的任何帖子(无论给定用户是否关注),而不返回任何重复项。< / p>

SELECT p.id, p.post, u.name, 
FROM following f 
JOIN posts p ON f.following = p.user_id
JOIN users u ON u.id = p.user_id 
WHERE f.user_id = :user;

以上内容会返回给定用户关注的所有帖子,但我也在努力弄清楚如何包含提及(请记住,用户无需关注某人即可查看帖子他们已被提及。)

更新: 感谢John R,我能够解决这个问题:

SELECT DISTINCT(p.id), p.post, u.name 
FROM posts p 
LEFT JOIN following f ON f.following = p.user_id
LEFT JOIN mentions m ON m.posts_id = p.id 
JOIN users u ON u.id = p.user_id
WHERE (f.user_id = :user_id OR m.user_id = :user_id)

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你会希望左联接包含任何提及..但不会过滤掉任何关注者/帖子

如果您可以添加一些示例数据,我可以确保它的工作方式...

SELECT 
    if(p.id is not null, p.id, p1.id) as post_id, 
    if(p.post is not null, p.post, p1.post) as post_text, 
    u.username, m.id, m.user_id
FROM posts p
JOIN users u on u.id = p.user_id
JOIN following f on f.user_id_of_user_being_followed = u.id
LEFT JOIN mentions m on m.user_id = f.user_id
LEFT JOIN posts p1 on p1.id = m.post_id
WHERE f.user_id = :user or m.user_id = :user;

我将联接提及留给了帖子,并且当提及表中的user_id等于指定的用户时过滤掉其他用户。左连接不应该更改返回的行数..但只包括任何提及


编辑: WORKING FIDDLE

在玩完它后,我意识到它试图将所有数据放入一行..试试这个:

(
    SELECT p.id, p.post_text, u.name
    FROM posts p
    JOIN users u on u.id = p.user_id
    JOIN following f on f.user_id_of_user_being_followed = u.id
    WHERE f.user_id = 1
)
UNION
(
    SELECT p.id, p.post_text, u.name
    FROM following f
    JOIN mentions m on m.user_id = f.user_id
    JOIN posts p on p.id = m.post_id
    join users u on u.id = p.user_id
    WHERE f.user_id = 1
);

答案 1 :(得分:-1)

也许你继承了这个db;但最后一张表并不符合良好的数据规范化。该表应该是id和following_id;设置时,您最终会用完列(或者在用户收到错误时必须继续添加它们) - 新用户无法关注任何人。