是否有一个与SQL NULL“相反”的概念?

时间:2018-03-15 18:36:29

标签: sql oracle

是否存在一个概念(在Oracle SQL中用于初学者),其行为类似于“通用”匹配器?

我的意思是;我知道NULL不等于任何东西 - 包括NULL。 这就是为什么你必须小心'IS NULL'而不是SQL表达式中的'= NULL'。

我也知道使用NVL(在Oracle中)函数检测NULL并将其替换为输出中的某些内容非常有用。

但是:使用NVL替换NULL必须匹配基础列的数据类型;否则你(正确地)会收到错误。

一个例子:

我有一个表格,其中NULLABLE列'name'的类型为VARCHAR2;这包含一个NULL行。

我可以取出NULL并将其替换为这样的NVL:

SELECT NVL(name, 'NullyMcNullFace’) from my_table;

但是如果列发生在NUMBER(比如'age'),那么我必须更改我的NVL:

SELECT NVL(age, 32) from my_table;

也很棒。

现在,如果该列恰好是DATE(比如'somedate'),那么我必须再次更改我的NVL:

SELECT NVL(somedate, sysdate) from my_table;

我在这里得到的是:为了处理NULL,你必须用特定的替换;那个特定的某些东西必须“适合”数据类型。

这里有一个构造/概念(因为想要一个更好的词),比如'ANY'。 其中'ANY'适合任何数据类型的列(如NULL),但(与NULL不同,与所有其他特定值不同)将匹配 ANYTHING (包括NULL - ?可能是urghhh dunno)。

所以我可以这样做:

SELECT NVL(whatever_column, ANY) from my_table;

我认为答案可能不是;并且可能“消失了,NULL已经足够糟糕了 - 不要介意你想到的那个怪物。”

4 个答案:

答案 0 :(得分:1)

不,SQL中没有“通用接受者”值等于一切。

您可以做的是将NVL提升到您的比较中。就像你正在尝试加入一样:

SELECT ...
FROM my_table AS m
JOIN other_table AS o ON o.name = NVL(m.name, o.name)

因此,如果m.name为NULL,则联接会将o.nameo.name进行比较,这当然是正确的。

对于NULL的其他用途,您可能必须使用另一种适合该情况的技术。

答案 1 :(得分:1)

在Bill Karwin的回答评论中解答问题:

  

如果NEW和OLD值不同,我想输出1,如果它们相同,我想输出0。但是(为了我的目的)我也想为两个NULLS返回0。

select
    Case When (:New = :Old) or 
              (:New is NULL and :Old is NULL) then 0
         Else
              1
    End
from dual

答案 2 :(得分:1)

在WHERE CLAUSE中你可以设置这样的条件,

WHERE column1 LIKE NVL(any_column_or_param, '%')

答案 3 :(得分:1)

也许DECODE()适合您的目的?

WITH t1 AS (SELECT 1 ID, NULL val FROM dual UNION ALL
            SELECT 2 ID, NULL val FROM dual UNION ALL
            SELECT 3 ID, 1 val FROM dual UNION ALL
            SELECT 4 ID, 2 val FROM dual UNION ALL
            SELECT 5 ID, 5 val FROM dual),
     t2 AS (SELECT 1 ID, NULL val FROM dual UNION ALL
            SELECT 2 ID, 3 val FROM dual UNION ALL
            SELECT 3 ID, 1 val FROM dual UNION ALL
            SELECT 4 ID, 4 val FROM dual UNION ALL
            SELECT 6 ID, 5 val FROM dual)
SELECT t1.id t1_id,
       t1.val t1_val,
       t2.id t2_id,
       t2.val t2_val,
       DECODE(t1.val, t2.val, 0, 1) different_vals
FROM   t1
       FULL OUTER JOIN t2 ON t1.id = t2.id
ORDER BY COALESCE(t1.id, t2.id);

     T1_ID     T1_VAL      T2_ID     T2_VAL DIFFERENT_VALS
---------- ---------- ---------- ---------- --------------
         1                     1                         0
         2                     2          3              1
         3          1          3          1              0
         4          2          4          4              1
         5          5                                    1
                               6          5              1