【问题标题】:Sql join 3 tablessql连接3张表
【发布时间】:2011-02-17 19:30:14
【问题描述】:

我很难产生好的 SQL。 它是应用程序的关系部分。 我有 3 个表:users('id')、relationship('user_id'、'member_id')、relationship_block('user_id'、'blocked_member_id')

我想获取属于 user_id 且未被阻止的用户的所有成员。

在“relationships”表中但不在“relationship_blocked”表中的第一个表“用户”的记录。 前 2 个我可以使用 JOIN,但是我想删除那些被阻止的。

谢谢。

编辑:在这里找到了一个很好的信息:http://explainextended.com/2010/05/27/left-join-is-null-vs-not-in-vs-not-exists-nullable-columns/

【问题讨论】:

    标签: mysql


    【解决方案1】:
    /* this would get the user */
    SELECT *
    FROM users
    WHERE id = $ID
    
    /* build on this to get relationships */
    SELECT *
    FROM users u
    JOIN relationship r ON r.user_id = u.id
    WHERE u.id = $ID
    
    /* build on this to get not blocked */
    SELECT *
    FROM users u
    JOIN relationship r ON r.user_id = u.id
    JOIN relationship_block b ON b.user_id = u.id
    WHERE u.id = $ID
      AND r.member_ID <> b.blocked_member_id
    
    /* get all users that NO ONE has blocked */
    /* this means if there exists a record b such that b.blocked_member_id
       equals the user X has blocked user Y, do not include user Y.
       By extension, if X and Y are fierce enemies and have blocked eachother,
       neither would get returned by the query */
    SELECT *
    FROM users u
    JOIN relationship r ON r.id = u.id
    WHERE NOT EXISTS ( SELECT null
                       FROM relationship_block rb
                       WHERE rb.blocked_member_id = u.id
                     )
    /* This runs two queries at once. The inner query says "I'm not getting any
       columns, because I don't care about the actual data, I just to get all
       records where someone has blocked the user I'm currently looking for".
       Then you select all users where that isn't true. For good speed, this would
       require an index on relationship_block.blocked_member_id */
    

    【讨论】:

    • 作为旁注,不要SELECT * ...这仅用于说明目的!
    • 我突然想到,这可以解释为您需要三个查询才能完成这项工作。你没有。前两个只是展示了我将如何构建所需查询的思路。
    • 我可能做错了什么,但这似乎不起作用。可能是在 relationship_blocks 表中只有一两行(块),但用户行更多。
    • 在更简单的解释中,我需要从关系表(所有 member_ids)中返回不存在于 relationship_blocks 表中的所有成员。因此,例如,如果 relationship_blocks 表中没有行,它将返回所有用户。如果 relationship_blocks 表中有 1 行具有:'user_id' = 1 ,'blocked_member_id' = 4,那么它将返回所有用户(在关系表中显示为 member_id),除了 id 为 4 的用户
    • 感谢您的解决方案。这现在可以工作了。虽然对于我的应用程序的性质,我不能将 2 个选择混合为一个,所以我将使用下面的解决方案。谢谢你。对于其他寻找相同事物的人,我在这里找到了很好的信息:link
    【解决方案2】:
    select *
        from users u
            inner join relationship r
                on u.user_id = r.user_id
            left join relationship_block rb
                on r.user_id = rb.user_id
                    and r.member_id = rb.blocked_member_id
        where rb.user_id is null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-20
      • 2023-04-05
      • 2011-09-18
      • 2017-07-17
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      相关资源
      最近更新 更多