为什么NVL()在以下外连接(+)中不起作用?

时间:2016-06-11 11:42:37

标签: sql oracle outer-join nvl

我正在尝试外连接两个表,当“全名”列中显示空值时,将其替换为“没有人”。

外连接工作正常,问题是,null值仍为null,而不是'No one'。

以下是我的代码。

SELECT 
NVL(to_char(e.FIRST_NAME||' '||e.LAST_NAME),'No One') "Full Name",
d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS d
WHERE e.DEPARTMENT_ID(+)=d.DEPARTMENT_ID;

Follwing是结果的屏幕截图。 enter image description here

感谢您一看!

4 个答案:

答案 0 :(得分:5)

“NVL不起作用”,因为NVL的参数中始终至少有一个空格字符。

SELECT 
decode(e.FIRST_NAME||e.LAST_NAME,null,'No one',e.FIRST_NAME||' '||e.LAST_NAME) "Full Name",
d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS d
WHERE e.DEPARTMENT_ID(+)=d.DEPARTMENT_ID;

可能是一种可行的替代方案。

答案 1 :(得分:4)

与其他数据库不同,Oracle允许在字符串中连接NULL值。

我会将您的查询编写为:

SELECT (CASE WHEN e.FIRST_NAME IS NULL AND e.LAST_NAME IS NULL THEN 'No One'
             WHEN e.FIRST_NAME IS NULL THEN e.LAST_NAME
             WHEN e.LAST_NAME IS NULL THEN e.FIRST_NAME
             ELSE e.FIRST_NAME || ' ' || e.LAST_NAME
        END) "Full Name", d.DEPARTMENT_NAME
FROM DEPARTMENTS d LEFT JOIN
     EMPLOYEES e
     ON e.DEPARTMENT_ID = d.DEPARTMENT_ID;

注意:

  • 这使用了正确的显式JOIN语法。连接的(+)表示法很古老而且已弃用。您应该学习正确的显式JOIN语法。
  • 当缺少其中一个值时,逻辑在名称的开头/结尾不再有额外的空格。
  • 逻辑是显式的,使用ANSI标准CASE表达式。

另外,还有一些缩短表达方式的奇特方法:

coalesce(trim(e.FIRST_NAME || ' ' || e.LAST_NAME), 'No One')

我认为case逻辑更清晰。

答案 2 :(得分:2)

因为表达式e.FIRST_NAME||' '||e.LAST_NAME永远不会为空。如果行是外连接的,则值为' '

答案 3 :(得分:0)

由于还没有人提及,你可以使用格式为

的NVL2
NVL2(<expression>, <value if expression is not null>, <value if expression is null>)

所以你可以这样做:

NVL2(e.FIRST_NAME||e.LAST_NAME, TRIM(e.FIRST_NAME||' '||e.LAST_NAME), 'No One') "Full Name"

TRIM是这样的:第一个或最后一个名称可能为空(但不是两个);它会删除剩余的尾随/前导空间。