SQL с использованием If Not Null на конкатенации

Если у меня есть таблица

введите описание изображения здесь

SELECT (Firstname || '-' || Middlename || '-' || Surname)  AS example_column
FROM example_table

Это отобразит имя-имя-имя-имя-друга, например.

John--Smith
Jane-Anne-Smith

Второй (Janes) отображается правильно, однако, поскольку у John нет имени middlame, я хочу, чтобы он игнорировал вторую тире.

Как я могу поместить выражение IF Middlename = NULL, чтобы он просто отображал John-Smith

Ответ 1

Вот мои предложения:

PostgreSQL и другие базы данных SQL, где 'a' || NULL IS NULL 'a' || NULL IS NULL, затем используйте COALESCE:

SELECT firstname || COALESCE('-' || middlename, '') || '-' || surname ...

Oracle и другие базы данных SQL, где 'a' || NULL = 'a' 'a' || NULL = 'a':

SELECT first name || DECODE(middlename, NULL, '', '-' || middlename) || '-' || surname...

Мне нравится идти для краткости. Здесь не очень интересно любому программисту по обслуживанию, является ли второе имя пустым или нет. Переключатели CASE прекрасно работают, но они громоздки. Я хотел бы избежать повторения того же имени столбца ("отчество"), где это возможно.

Как отметил @Prdp, ответ зависит от СУБД. Что конкретно, так это то, рассматривает ли сервер строку нулевой длины как эквивалентную NULL, что определяет, дает ли конкатенация NULL NULL или нет.

Обычно COALESCE наиболее лаконичен для обработки пустых строк в стиле PostgreSQL и DECODE (*VALUE*, NULL, ''... для обработки пустых строк в стиле Oracle.

Ответ 2

Если вы используете Postgres, concat_ws() - это то, что вы ищете:

SELECT concat_ws('-', Firstname, Middlename, Surname)  AS example_column
FROM example_table

SQLFiddle: http://sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/8812

Для обработки пустых строк или строк, которые содержат только пробелы, такие как NULL используйте nullif():

 SELECT concat_ws('-', Firstname, nullif(trim(Middlename), ''), Surname)  AS example_column
 FROM example_table

Ответ 3

Этот подход работает:

select first_name || coalesce('-' || middle_name, '') || '-' || last_name 
from t;

Вывод:

|        ?column? |
|-----------------|
|      john-smith |
| jane-anne-smith |

UPDATE

Живой код: http://sqlfiddle.com/#!15/d5a1f/1

Так же, как мой намек, кто-то даст сценарий, которого нет в этом вопросе. Поэтому, чтобы заставить его работать с пустым средним именем. Просто добавьте nullif для пустой строки:

select first_name || coalesce('-' || nullif(middle_name,'') , '') || '-' || last_name 
from t;

Вывод:

|        ?column? |
|-----------------|
|      john-smith |
|      obi-kinobi |
| jane-anne-smith |

Ответ 4

Это может быть жизнеспособным вариантом:

SELECT FirstName || '-' || ISNULL(MiddleName + '-', '') || Surname

Так как NULL, связанный со строкой, дает NULL, мы можем попытаться построить нашу подстроку и заменить NULL пустой строкой, которая затем будет объединена со следующей частью имени.

Это предполагает, что FirstName и Surname всегда не являются NULL, но вы можете применить к ним ту же логику.

Ответ 5

Вы можете использовать REPLACE (если Oracle)

SELECT
   REPLACE(Firstname || '-' || Middlename || '-' || Surname,'--','-') 
   AS example_column
FROM example_table;

Предупреждение: я предположил, что нет правильного имени с - в качестве первого или последнего символа.


Для downvoter

OP ясно сказал, что:

SELECT (Firstname || '-' || Middlename || '-' || Surname)  AS example_column
FROM example_table

Это отобразит имя-имя-имя-имя-друга, например.

Джон - Смит

Итак:

  • Middlename пусто: '' это решение работает в SQLite/PostgreSQL/Oracle
  • Middlename NULL и OP, вероятно, использует Oracle

Хотя Oracle обрабатывает нулевые строки с нулевой длиной в качестве нулей, объединение символьной строки нулевой длины с другим операндом всегда приводит к другому операнду, поэтому null может быть результатом только конкатенации двух нулевых строк.

|| оператор конкатенации:

 -- PostgreSQL/SQLite
 SELECT 'sth' || NULL
 -- NULL


 -- Oracle
 SELECT 'sth' || NULL
 -- sth

Ответ 6

В одном решении может использоваться case statement

select case Middlename is not null then (Firstname || '-' || Middlename || '-' || Surname) 
    else (Firstname || '-' || Surname) end AS example_column
from ....

Ответ 7

Вы можете использовать оператор CASE

select Firstname 
      || case when Middlename <> '' Then '-'||Middlename  else '' END 
      || case when Surname<> '' Then '-'||Surname else '' END

В соответствии с вашими выборочными данными я проверяю empty string. Чтобы проверить NULL, используйте Middlename IS NOT NULL вместо Middlename <> ''

Ответ 8

  • Выражение NULLIF уменьшает пробел Middlename до NULL
  • Конкатенирование '-' с помощью NULL всегда будет возвращать NULL
  • VALUE выражение заменяет NULL пустой строкой

_

SELECT Firstname || VALUE( '-' || NULLIF('Middlename',''),'') || '-' || Surname'  
       AS example_column
FROM example_table