【问题标题】:Mysql join should return all from table A not in table B AND where clause for table BMysql 连接应该从表 A 中返回所有不在表 B 中的 AND 表 B 的 where 子句
【发布时间】:2020-10-01 04:56:45
【问题描述】:

我希望这是有道理的,我发现很多这样的问题,但不知道如何用最适合我的具体情况来表达。

我有表A,是用户表,表B是不同类型过滤器的过滤器表:

table A - User
    id, name, email

table B - Filters
    id, filter_type, user_id

因此,用户可以拥有任意数量的过滤器类型 - 或根本没有。

我需要一个连接查询来获取所有未被过滤为请求类型的用户,即使它们不存在于表 B 中。

所以如果我有用户数据:

1, John, john@gmail.com
2, Mike, mike@gmail.com
3, Fred, fred@gmail.com

只为 John 设置了过滤器:

id | type | user_id
----------------
1, type1, 1
2, type2, 1

假设我们有过滤器类型:type1、type2、type3,我需要所有用户,除了那些对 type1 有过滤器的用户,我仍然应该找回 john:type2 和 type3,以及 Mike 和 Fred 的所有用户。

希望这是有道理的

我从以下开始:

select u.id, u.name, f.type from users u
left join filters f on f.user_id = u.id
where f.type != 'type1'

这仅返回 John type2 和 type3 .... 但不包括 Mike 和 Fred。 我也尝试过不同的连接类型,但我不清楚 where 子句,任何提示都表示赞赏

【问题讨论】:

    标签: mysql


    【解决方案1】:

    继续您当前的尝试,您希望在此处加入反连接,因此您需要在 WHERE 子句中添加另一个标准:

    SELECT u.id, u.name
    FROM users u
    LEFT JOIN filters f
        ON f.user_id = u.id AND f.type = 'type1'
    WHERE
        f.user_id IS NULL;
    

    但是,我觉得使用存在逻辑来表达您的查询更明智:

    SELECT u.id, u.name
    FROM users u
    WHERE NOT EXISTS (SELECT 1 FROM filters f
                      WHERE f.user_id = u.id AND f.type = 'type1');
    

    【讨论】:

    • 完美-我认为对于我正在使用的结构,第一个答案很棒,谢谢会尽快标记
    • @yoyoma 第一个查询中的“技巧”(实际上很容易搞砸)是过滤器限制进入连接的ON 子句。这意味着不匹配的用户将拥有filters 表中所有字段的NULL“漏洞”。然后,我们只保留与type1 过滤器匹配的用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 2016-08-28
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多