2016-06-11 95 views
1

我试图外连接两个表,并且当“全名”列中显示空值时,将其替换为“无人”。为什么NVL()在下面的外连接(+)中不起作用?

外连接工作正常,问题是,空值仍为空,而不是'没有人'。

以下是我的代码。

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

感谢您的光临!

+1

我会使用[coalesce](https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions023.htm)而不是'NVL' –

回答

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; 

可能是一个可行的选择。

+0

这就是问题所在!谢谢!但是当我还想保留名字和姓氏之间的空格时,我应该如何解决这个问题?@ user2672165 – Wilheim

+0

@Wilheim添加了一条建议。 – user2672165

+0

这很完美!谢谢! @ user2672165 – Wilheim

2

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

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逻辑更清晰。

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是情况下,它可能有二:第一或姓氏可以为空(但不能同时为);它会移除将留下的拖尾/前导空间。

相关问题