是否存在一个概念(在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已经足够糟糕了 - 不要介意你想到的那个怪物。”
答案 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.name
与o.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