使用可以为null的列测试不等式

时间:2009-12-02 20:23:41

标签: sql database null nullable informix

所以,今天早上我问question,我没有正确说出,所以我得到了很多回复,为什么NULL与任何东西相比都会给出NULL / FALSE。

我的实际问题是,对于两个列都可以为NULL的两个列测试不等式的时尚是多少。我的问题与此question完全相反。

要求如下,A和B为两列:
a)如果A和B均为NULL,则它们相等,返回FALSE
b)如果A和B都不是NULL,则返回A<> B
c)如果A或B为NULL,它们不相等,则返回TRUE

9 个答案:

答案 0 :(得分:9)

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

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

诀窍是找到一个值(这里我用-1), NEVER 会出现在你的数据中。

另一种方式是:

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

这可能是一个问题,具体取决于您的特定RDBMS如何处理NULL。根据ANSI标准,这应该给你你想要的,但无论如何谁遵循标准。 :)

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

P.P.S。 - 我刚才注意到OMG Ponies提到Informix不支持COALESCE。这是我认为的ANSI标准功能,但看看我上面谈到的标准......

答案 1 :(得分:3)

我个人会写出你提出的表达方式,特别是如果表格预计会变大的话。在函数调用中包装列会使性能受损,因此引擎无法使用您在这些列上使用的任何索引。当然,在一个小表中,这可能不是任何问题,但我仍然喜欢以明确的方式进行,以防表格最终增长。

答案 2 :(得分:1)

你可以在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

答案 3 :(得分:0)

如果你想确定如何处理NULL,你将不得不使用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)

答案 4 :(得分:0)

对于SQL Server,请使用:

WHERE ISNULL(A, '') <> ISNULL(B, '')

答案 5 :(得分:0)

当一个或两个操作数为NULL时,问题是a<>b(或a=b)产生NULL,而不是10。这与=案例无关,因为NULL OR 11NULL OR 0NULL,其行为类似于0,可用于{ {1}}条款。

你可以说:

WHERE

然而,无论哪种方式都需要这样做可能表示您误用了NULL,并且应该考虑更改架构以使用其他一些NOT NULL值来表示这种可比较的条件。

例如,如果您的a<>b OR (a IS NULL)<>(b IS NULL) 表格中包含person列,请不要使用NULL表示它们没有标题;这不是一个“缺失”的数据,只是没有标题存在。因此,将其存储为空字符串title,您可以愉快地与其他空字符串进行比较。 (除非您运行Oracle,当然还有空字符串问题......)

答案 6 :(得分:0)

IBM Informix Dynamic Server对于各种历史(又称“坏”)原因的布尔值有一些特殊的看法。改编@astander提出的想法,这个CASE表达式“有效”,但我会是第一个说“不明显”的人(参见 - 我之前说过你!)。设置阶段:

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无法将FALSE或TRUE或UNKNOWN识别为关键字。
  • IDS无法识别布局表达式,例如'a!= b'(或'a&lt;&gt; b')。

是的,必须说明这一点,这让我很痛苦。

答案 7 :(得分:0)

如果

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

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

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

不平等?

答案 8 :(得分:0)

@user3830747 answer 的轻微修改,基于 demorgans law

NOT (NVL(a = b,FALSE) OR COALESCE(a,b) IS NULL)