MySQL CONCAT возвращает NULL, если любое поле содержит NULL


163

У меня есть следующие данные в моей таблице "устройства"

affiliate_name  affiliate_location  model     ip             os_type    os_version 

cs1             inter               Dell     10.125.103.25   Linux      Fedora  
cs2             inter               Dell     10.125.103.26   Linux      Fedora  
cs3             inter               Dell     10.125.103.27   NULL       NULL    
cs4             inter               Dell     10.125.103.28   NULL       NULL    

Я выполнил ниже запрос

SELECT CONCAT(`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`) AS device_name
FROM devices

Возвращает результат, указанный ниже

cs1-Dell-10.125.103.25-Linux-Fedora
cs2-Dell-10.125.103.26-Linux-Fedora
(NULL)
(NULL)

Как из этого выйти так, чтобы он игнорировал NULL И результат должен быть

cs1-Dell-10.125.103.25-Linux-Fedora
cs2-Dell-10.125.103.26-Linux-Fedora
cs3-Dell-10.125.103.27-
cs4-Dell-10.125.103.28-

Ответы:


280

преобразовать NULLзначения с пустой строкой, обернув ееCOALESCE

SELECT CONCAT(COALESCE(`affiliate_name`,''),'-',COALESCE(`model`,''),'-',COALESCE(`ip`,''),'-',COALESCE(`os_type`,''),'-',COALESCE(`os_version`,'')) AS device_name
FROM devices

1
Вы можете использовать if, выбрав CONCAT (если (affiliate_name имеет значение null, '', affiliate_name), '-', if (model is null, '', affiliate_name)) в качестве модели из устройств
Динеш Рабара

6
Для тех, кто интересуется, как я это сделал, что COALESCEделает функция: она возвращает первый ненулевой NULLпараметр, переданный ей (или, NULLесли все параметры есть NULL). Передавая пустую строку в качестве второго параметра, вы гарантируете, что он не вернется NULL.
Джо.

3
MySQL имеет IFNULL (arg, по умолчанию) вместо COALESCE с тем же синтаксисом
Василий Суриков

126

Вместо этого используйте CONCAT_WS :

CONCAT_WS () не пропускает пустые строки. Однако он пропускает любые значения NULL после аргумента разделителя.

SELECT CONCAT_WS('-',`affiliate_name`,`model`,`ip`,`os_type`,`os_version`) AS device_name FROM devices

Извините, neeraj, я пропустил '_' между Concat и WS. Пожалуйста, попробуйте еще раз с CONCAT_WS (). Я обновил ответ, пожалуйста, проверьте,
Gurmeet

8
Обратите внимание, что это решение скрывает полный «столбец» (включая разделитель), если одно из средних полей имеет значение NULL. Таким образом, этот ответ является правильным только в том случае, если только последние поля могут быть пустыми. В зависимости от ваших потребностей ответ COALEASE () ниже может быть лучше.
Янн

Это работает, только если вы хотите, чтобы каждый член разделялся одним и тем же разделителем. CONCAT не имеет этого ограничения. Я разместил решение в качестве ответа здесь
Патрик

12

Чтобы иметь такую ​​же гибкость в CONCAT_WS, как и в CONCAT (если вы не хотите использовать один и тот же разделитель для каждого члена, например), используйте следующее:

SELECT CONCAT_WS("",affiliate_name,':',model,'-',ip,... etc)


11

CONCAT_WSвсе еще производит нуль для меня, если первое поле Нуль. Я решил это, добавив строку нулевой длины в начале, как в

CONCAT_WS("",`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`)

тем не мение

CONCAT("",`affiliate_name`,'-',`model`,'-',`ip`,'-',`os_type`,'-',`os_version`) 

выдает Null, когда первое поле равно Null.


очевидно, потому что первое поле - это строка, с которой оно будет связано (WS = со строкой)
Bouke Versteegh,

2
CONCAT_WS - сокращение от конкатенации с разделителем. Первый параметр является разделителем и не может быть нулевым. Это, вероятно, то, что вы хотите вместо этого:CONCAT_WS("-", affiliate_name, model, ip, os_type, os_version)
захватить

2

Вы можете использовать, если заявление, как показано ниже

select CONCAT(if(affiliate_name is null ,'',affiliate_name),'- ',if(model is null ,'',affiliate_name)) as model from devices
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.