代码之家  ›  专栏  ›  技术社区  ›  rouble

用可以为空的列测试不等式

  •  12
  • rouble  · 技术社区  · 15 年前

    所以,我问 question 今天早上,我说的不对,所以我得到了很多答案,为什么与任何东西相比,空值会给出空/假。

    我的实际问题是,DB人员测试两列都可以为空的不等式的方式由来已久。我的问题恰恰相反 question .

    要求如下,A和B为两列:
    a)如果a和b都为空,则它们相等,返回false
    b)如果A和B都不为空,则返回A<>B
    c)如果a或b为空,则它们不相等,返回true。

    8 回复  |  直到 9 年前
        1
  •  9
  •   Tom H zenazn    15 年前

    取决于数据类型和列的可能值:

    COALESCE(A, -1) <> COALESCE(B, -1)
    

    诀窍是找到一个值(这里我使用-1),它将 从未 出现在数据中。

    另一种方法是:

    (A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)
    

    这可能是一个问题,具体取决于您的特定RDBMS如何处理空值。按照美国国家标准协会的标准,这应该给你想要的,但谁遵守标准无论如何。:)

    P.S.-我还应该指出,在比较列时使用coalesce函数可能会使索引的使用失效。检查您的查询计划和查询的性能,看看是否有问题。

    P.P.S.-我刚注意到OMG小马提到Informix不支持合并。我相信这是一个ANSI标准函数,但是看看我上面说的关于标准的内容…

        2
  •  3
  •   Donnie    15 年前

    我会亲自写出你想出的表达方式,特别是如果桌子预计会变大的话。在函数调用中包装列会损害性能,因为这样引擎就不能在这些列上使用任何索引。当然,在一个小的表中,这可能不是什么问题,但我仍然喜欢以明确的方式进行,以防表最终增长。

        3
  •  1
  •   Adriaan Stander    15 年前

    你能在Informix中尝试类似的方法吗?

    CASE
        WHEN a IS NULL AND B IS NULL THEN false 
        WHEN a IS NULL OR B IS NULL THEN true
        ELSE a <> B
    END
    

    IBM Informix Guide to SQL: Syntax , CASE Expressions

        4
  •  0
  •   OMG Ponies    15 年前

    如果您想确定如何处理空值,则必须使用Informix支持的任何内容来检查空值。除了SE版本不支持Coalesce之外,我还没有找到其他版本,但它确实支持decode和case。

    WHERE COALESCE(t.a, 0) != COALESCE(t.b, 0)
    WHERE DECODE(NULL, 0, t.a) != DECODE(NULL, 0, t.b)
    
        5
  •  0
  •   Gordon Bell    15 年前

    对于SQL Server,请使用:

    WHERE ISNULL(A, '') <> ISNULL(B, '')
    
        6
  •  0
  •   bobince    15 年前

    问题是 a<>b (或) a=b 产量 NULL 不是 1 0 当一个或两个操作数都为空时。这不重要 = 案件因为 NULL OR 1 NULL OR 0 无效的 表现得像 用于在 WHERE 条款。

    你可以说:

    a<>b OR (a IS NULL)<>(b IS NULL)
    

    但是,无论哪种方式都需要这样做,这可能是您滥用了空值的迹象,应该考虑更改架构,使用其他非空值来表示这个可比较的条件。

    例如,如果你有一个 person A表 title 列中,不要使用空来表示它们没有标题;这不是一个缺少数据,只是没有标题存在。所以把它存储为空字符串 '' 与其他空字符串相比,您可以感到高兴。(当然,除非运行Oracle,因为它有空字符串问题…)

        7
  •  0
  •   Jonathan Leffler    15 年前

    IBMInformixDynamicServer由于各种历史原因(也叫“坏”)对布尔值有一种特殊的看法。修改@astander建议的想法,这个案例表达式“有效”,但我会第一个说“不明显”(见-我在你之前说过!)。设置阶段:

    create table x(a int, b int);
    insert into x values(null, null);
    insert into x values(null, 1);
    insert into x values(1, null);
    insert into x values(1, 1);
    insert into x values(1, 2);
    

    select语句:

    SELECT *
      FROM x
      WHERE   CASE
              WHEN a IS NULL AND b IS NULL THEN 'f'::BOOLEAN
              WHEN a IS NULL OR  b IS NULL THEN 't'::BOOLEAN
              WHEN a != b                  THEN 't'::BOOLEAN
              ELSE                              'f'::BOOLEAN
              END
    ;
    

    此查询的结果是:

                     1
          1           
          1          2
    

    问题:

    • IDS不将假、真或未知识别为关键字。
    • ID不识别布尔表达式,如“a!”=b'(或'a<gt;b')如是。

    是的,这让我非常痛苦。

        8
  •  0
  •   user3830747    9 年前

    如果

    where ((A=B) OR (A IS NULL AND B IS NULL))
    

    是为了平等,那为什么不使用:

    where NOT (
      ((A=B) OR (A IS NULL AND B IS NULL))
    )
    

    为了不平等?