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