【问题标题】:Get unique records based on multi-join with conditionals基于带条件的多连接获取唯一记录
【发布时间】:2014-06-27 17:48:38
【问题描述】:

我有 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 拥有提及 1 个或多个其他用户的任何帖子的帖子 ID 和用户 ID following 有一个用户 id 和他们关注的用户(用户可以关注 0 到多个用户)

我要做的是返回给定用户关注的用户的所有帖子,加上任何提到该用户的帖子(无论给定用户是否关注),而不返回任何重复项。

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)

【问题讨论】:

    标签: mysql


    【解决方案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
    );
    

    【讨论】:

    • hmm,这似乎不起作用,因为我们已经根据JOIN posts p ON f.following = p.user_id 限制了返回的帖子 - 至少我认为这就是原因。
    • 您能提供几行数据供我使用吗?如果你这样做,我可以看到我在理论上错过了它
    • 编辑了原帖。如您所见,用户 1 仅关注用户 2,但是用户 3 在帖子 4 中提到了用户 1。因此用户 1 应该看​​到来自用户 2 的所有帖子,以及他们被提及的帖子(由提及表定义)。
    • @kylex 我刚刚编辑了我的查询.. sql fiddle 有时会给出一些奇怪的结果,所以它没有完全正确地显示出来.. 但是数据仍然存在...尝试执行该查询..跨度>
    • 我明白了,我给你一个赞成票,因为你帮助我到达了那里。我会在一分钟后在编辑中发布我的解决方案。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      相关资源
      最近更新 更多