【问题标题】:MySQL SELECT x FROM a WHERE NOT IN ( SELECT x FROM b ) - Unexpected resultMySQL SELECT x FROM a WHERE NOT IN (SELECT x FROM b) - 意外结果
【发布时间】:2010-11-03 07:44:02
【问题描述】:

我希望下面第三个查询的结果包含 id=732。它没有。这是为什么呢?

mysql> SELECT id FROM match ORDER BY id DESC LIMIT 5 ; +------------+ |编号 | +------------+ |第732章 | 730 | | 655 | |第458章 |第456章 +------------+ 5 行一组(0.00 秒) mysql> SELECT id FROM email ORDER BY id DESC LIMIT 5 ; +------------+ |编号 | +------------+ |第731章 |第727章 | 725 | |第724章 |第723章 +------------+ 5 行一组(0.00 秒) mysql> SELECT * FROM match WHERE id NOT IN (SELECT id FROM email); 空集(0.00 秒)

email.id 表中有 3 个 NULL 条目,match.id 中没有 NULL 条目。

完整的表/查询可以在http://pastebin.ca/1462094看到

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    来自documentation:

    为了符合SQL 标准,IN 不仅会在左侧的表达式为 NULL 时返回 NULL,而且如果在列表中未找到匹配项且在列表是NULL。

    这正是你的情况。

    IN 和 NOT IN 都返回 NULL,这不是 WHERE 子句可接受的条件。

    按如下方式重写您的查询:

    SELECT  *
    FROM    match m
    WHERE   NOT EXISTS
            (
            SELECT  1
            FROM    email e
            WHERE   e.id = m.id
            )
    

    【讨论】:

    • 是OP的情况吗?我的理解是“如果没有找到匹配项并且列表中的表达式之一为 NULL”不是这种情况,因为应该找到 732,从而使该子句无效,对吧?
    • @Eric:在电子邮件中找不到 732。
    【解决方案2】:

    ...或者如果你真的想使用NOT IN,你可以使用

    SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email WHERE id IS NOT NULL)
    

    【讨论】:

    • 这对我有用,想创建一个尚未选择的“仪表类型”下拉列表,即第二个表中没有记录
    • 我更喜欢这个答案。不知道“where id is not null null”是使“不在”查询工作所必需的。
    【解决方案3】:

    我对 MySQL 如何处理空值的细节有点脱节,但这里有两件事可以尝试:

    SELECT * FROM match WHERE id NOT IN 
        ( SELECT id FROM email WHERE id IS NOT NULL) ;
    
    SELECT
        m.*
    FROM
        match m
        LEFT OUTER JOIN email e ON
            m.id = e.id
            AND e.id IS NOT NULL
    WHERE
        e.id IS NULL
    

    第二个查询看起来违反直觉,但它先是连接条件,然后是 where 条件。这就是连接和 where 子句不等价的情况。

    【讨论】:

    • 我的理解是使用左外连接对性能也更好。
    【解决方案4】:

    下面是一些真正有意义的 SQL:

    SELECT m.id FROM match m LEFT JOIN email e ON e.id = m.id WHERE e.id IS NULL
    

    简单总是更好。

    【讨论】:

    • 虽然不直观,但实际上是最有效的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2012-01-13
    • 2013-02-28
    • 2022-11-12
    • 2019-06-16
    • 2010-10-12
    相关资源
    最近更新 更多