Sql 为什么NVL()不';t在以下外部联接(+;)中工作?

Sql 为什么NVL()不';t在以下外部联接(+;)中工作?,sql,oracle,outer-join,nvl,Sql,Oracle,Outer Join,Nvl,我正在尝试外部联接这两个表,当“Full Name”列中显示空值时,将其替换为“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_I

我正在尝试外部联接这两个表,当“Full Name”列中显示空值时,将其替换为“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;
下面是结果的屏幕截图。

谢谢你看

“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;
可能是一个可行的替代方案。

由于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;

可能是一个可行的选择。

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

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

与其他数据库不同,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')

我只是觉得
案例的逻辑要清晰得多。

与其他数据库不同,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')

我只是觉得
案例的逻辑要清晰得多。

因为还没有人提到它,你可以使用NVL2,它的形式如下:

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

修剪是一种情况,可能是名字或姓氏都可以为空(但不能同时为空);它将删除剩余的尾随/前导空间。

因为还没有人提到它,您可以使用NVL2,其形式如下:

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

修剪是一种情况,可能是名字或姓氏都可以为空(但不能同时为空);它将删除剩余的尾随/前导空间。

我将使用而不是
NVL
我将使用而不是
NVL
,这就是问题所在!谢谢但是,当我仍然想保留名字和姓氏之间的空格时,我应该如何解决这个问题呢@user2672165@Wilheim添加了一个建议。这就是问题所在!谢谢但是,当我仍然想保留名字和姓氏之间的空格时,我应该如何解决这个问题呢@user2672165@Wilheim增加了一个建议。