简体   繁体   English

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

[英]Why NVL() doesn't work in the following outer join(+)?

I'm trying to outer join the two tables, and when there is a null value displayed in the column of "Full Name", replace it with 'No one'. 我试图外部连接两个表,并且当“全名”列中显示空值时,将其替换为“无人”。

The outer join worked fine, the problem is, the null value is still null, not 'No one'. 外部联接工作正常, 问题是空值仍然为空,而不是“无人”。

The following is my code. 以下是我的代码。

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 is a screenshot of the result. 以下是结果的屏幕截图。 在此处输入图片说明

Thanks for having a look! 感谢您的光临!

"NVL does not work" because there will always be at least a space character in the argument to NVL. “ 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;

could be a working alternative. 可能是一个可行的选择。

Unlike other databases, Oracle allows the concatenation of NULL values in strings. 与其他数据库不同,Oracle允许在字符串中串联NULL值。

I would write your query as: 我将您的查询写为:

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;

Notes: 笔记:

  • This uses proper explicit JOIN syntax. 这使用正确的显式JOIN语法。 The (+) notation for joins is ancient and deprecated. 联接的(+)表示法很古老且已过时。 You should learn proper explicit JOIN syntax. 您应该学习正确的显式JOIN语法。
  • The logic no longer has extra spaces at the beginning/end of a name, when one of the values is missing. 当缺少一个值时,逻辑在名称的开头/结尾不再有多余的空格。
  • The logic is explicit and uses the ANSI standard CASE expression. 逻辑是明确的,并使用ANSI标准CASE表达式。

And to add, there are fancy ways of shortening the expression: 此外,还有一些花哨的方法可以缩短表达式:

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

I just think the case logic is much clearer. 我只是认为case逻辑要清楚得多。

Because the expression e.FIRST_NAME||' '||e.LAST_NAME 因为表达式e.FIRST_NAME||' '||e.LAST_NAME e.FIRST_NAME||' '||e.LAST_NAME is never null. e.FIRST_NAME||' '||e.LAST_NAME永远不会为空。 In case the row is outer joined, the value is ' ' . 如果该行是外部联接的,则值为' '

Since no one mentioned it yet, you can use NVL2 which has the form: 由于尚无人提及,因此可以使用以下形式的NVL2:

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

So you could simply do: 因此,您可以简单地执行以下操作:

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

The TRIM is case it's possible that either the first or last name can be null (but not both); 在TRIM的情况下,名字或姓氏可能为null(但不能同时为两者); it would remove the trailing/leading space that would be left over. 它将删除剩余的尾随/前导空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM