代码之家  ›  专栏  ›  技术社区  ›  Jordan Parmer

有人能解释为什么这些问题在地球上是不一样的吗?

  •  2
  • Jordan Parmer  · 技术社区  · 15 年前

    我维护了一个如下的查询:

    select field_1, field_2
    from source_table
    minus
    select field_1, field_2
    from source_table
    where status_code in (3, 600);
    

    当我看到这个问题的时候,我立刻想,“这是跛脚的。为什么不直接用“不在”来去掉这个减号呢?所以我把它改写为:

    select field_1, field_2
    from source_table
    where status_code not in (3, 600);
    

    为了再次检查我的神智,我得到了每个查询的计数。令我惊讶的是,第一个查询返回了789089条记录,第二个查询返回了1518450条记录!

    我已经从多个角度研究过这个问题,但无法理解这两个查询是如何不同的。有人能解释发生了什么事吗?或者为什么我今天早上是个白痴?

    4 回复  |  直到 15 年前
        1
  •  9
  •   Alison R.    15 年前

    这些查询确实不同。 field_1 field2 不等于 status_code 3和600。 菲尔德1 可能是“A”和 field_2 可能是“b”,因此您将从第一个选择中删除看起来像 A, B .原版可能是获得正确结果的最佳方式。

    编辑:为了让您更好地了解正在发生的事情,您可以通过执行子查询以类似于编写查询的方式获得相同的结果:

    select distinct field_1, field_2
    from source_table
    where (field_1, field_2) not in (
        select field_1, field_2
        from source_table
        where status_code in (3, 600)
    );
    
        2
  •  4
  •   Alex Poole    15 年前

    如果对字段“1”和“2”的组合没有唯一约束,则第二个查询可能包含重复项,而第一个查询不包含重复项,因为“减号”将抑制它们。用“distinct”尝试第二个查询,看看计数是否匹配。

        3
  •  4
  •   Marcel Wolf    15 年前

    union、minus和intersect运算符只返回唯一值。如果有两行的字段_1和字段_2相同,则第一个查询将对其计数一次,而第二个查询将对其计数两次:

    SQL> insert into source_table values ('a', 'b', 10);
    
    SQL> insert into source_table values ('a', 'b', 10);
    
    SQL> select field_1, field_2
      2  from source_table
      3  minus
      4  select field_1, field_2
      5  from source_table
      6  where status_code in (3, 600);
    
    FIELD_1    FIELD_2
    ---------- ----------
    a          b
    
    SQL> select field_1, field_2
      2  from source_table
      3  where status_code not in (3, 600);
    
    FIELD_1    FIELD_2
    ---------- ----------
    a          b
    a          b
    
        4
  •  3
  •   ondra    15 年前

    如果您对字段_1、字段_2或两者都没有唯一的约束,那么Alison可能是对的。假设您有一张桌子: A 3 甲乙10

    第一个查询将删除这两行,第二个查询只删除一行。 或者,如果状态代码列中有空值,则可能会得到不同的结果(a或not a),如果列中有空值,则在SQL中不起作用。