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 AND результат повинен бути

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-

Відповіді:


279

конвертувати NULLзначення в порожній рядок, загорнувши йогоCOALESCE

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

1
Ви можете використовувати, якщо ви вибрали CONCAT (якщо (affiliate_name null, '', affiliate_name), '-', якщо (модель є нульовою, '', affiliate_name)) як модель з пристроїв
Dinesh Rabara

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

3
mysql має IFNULL (арг, за замовчуванням) замість COALESCE з тим же синтаксисом
Василь Суріцов

126

Замість цього використовуйте CONCAT_WS :

CONCAT_WS () не пропускає порожні рядки. Однак він пропускає будь-які значення NULL після аргументу роздільника.

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

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

8
Зауважте, що це рішення приховує повний "стовпчик" (включаючи роздільник), якщо одне із середніх полів NULL. Отже, ця відповідь є правильною лише за умови, що лише останнє поле може бути NULL. Залежно від вашої потреби, відповідь COALEASE () може бути кращим.
Яннес

Це працює лише в тому випадку, якщо потрібно, щоб кожен член був розділений одним і тим же роздільником. CONCAT не має цього обмеження. Я опублікував рішення як відповідь тут
Патрік

12

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

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


10

CONCAT_WSвсе ще видає null для мене, якщо перше поле - Null. Я вирішив це, додавши рядок нульової довжини на початку, як і в

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

проте

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

видає Null, коли першим полем є Null.


очевидно, тому що перше поле - це рядок, з яким він буде
поєднуватися

2
CONCAT_WS є коротким для Concatenate With Separator. Перший параметр є роздільником і не може бути нульовим. Це, мабуть, те, що ви хочете замість цього: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.