2016-06-11 2 views
1

Я пытаюсь выполнить внешнее соединение двух таблиц, и когда в столбце «Полное имя» отображается нулевое значение, замените его «Нет».Почему NVL() не работает в следующем внешнем соединении (+)?

Внешнее соединение работает нормально, проблема в том, что значение null по-прежнему равно null, а не «Никто».

Следующий мой код.

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

В этом проблема! Благодаря! Но как мне исправить это, когда я все еще хочу сохранить пространство между именем и фамилией[email protected] user2672165 – Wilheim

+0

@ Уильхайм добавил предложение. – user2672165

+0

Это работает отлично! Благодаря! @ user2672165 – Wilheim

2

Потому что выражение e.FIRST_NAME||' '||e.LAST_NAME никогда не имеет значения null. В случае, если строка является внешней, значение равно ' '.

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" 

обивку является случай, возможно, что либо первый или фамилия может быть нулевой (но не той и другой); он удалит конечное/ведущее пространство, которое будет оставлено.

Смежные вопросы